测试方向基础——网络编程浅析

网络编程基础

  1. 网络编程的目的:直接或间接的通过网络协议与其他计算机进行通信。
  2. 网络编程种有两个主要的问题:
    (1)如何准确定位网络上的一台或多台主机,
    (2)找到主机候如何高效地进行数据传输
    在TCP/IP协议中IP层主要负责主机的定位,由IP地址可以唯一确定Internet上的一台主机。网络编程一般不关心IP层是如何处理数据的。
  3. 目前较为流行的网络编程模型是客户端/服务器(C/S)结构,即通信双方一方作为服务器等待客户提出请求并予以响应,另一方则作为客户在需要服务时向服务器提出请求。
  4. 服务器一般作为守护进程始终运行,监听网络端口,一旦客户请求,就会启动一个独立线程来响应客户,同时自己继续监听服务端口,使后来的客户也能及时得到服务。

计算机网络:通过一定的物理设备将处于不同位置的计算机连接起来组成的网络

TCP/IP基本概念

  1. 主机名:网络地址的主机名,按照域名进行分级管理。例如:www. redmine.edu2act.org。
  2. IP地址:标识计算机等网络设备的网络地址,由4个8位的二进制数组成,中间以小数点分隔。例如:192.163.10.1。(由于IP地址不易记忆,引入网络域名来确认IP地址)
  3. 端口号:网络通信时同一机器上不同进程的标识。如80、21、23、25,其中1~1024为系统保留的端口号。精确确定客户访问的是这台主机中的哪个应用程序
    21 文件传输服务器(控制连接)(FTP)
    23 运程终端服务器(TELNET)
    25 简单邮件传输服务器(SMTP)
    80 万维网服务器(HTTP)
  4. 服务类型:网络的各种服务。如http、telnet、ftp、smtp。服务类型是TCP层上面的应用层概念

确定好目标主机和应用程序后,就可进行网络传输。数据传递的两种最常见的形式:

  1. TCP传输控制协议,面向连接的、可靠的、基于字节流的传输层通信协议
    首先要在网络两端建立安全连接,再进行数据传递,确保网络双方完整无误的传输数据

  2. UDP用户数据报协议,一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务。
    无需建立网络双方连接,直接发送数据包(包含目的地址信息),可能会因为网络问题导致数据传输失败等问题,但传输速度很快,常应用于局域网中传输数据

  3. Java语言中,实现网络编程需要两个核心类包:
    java.net.*:网络类包,涵盖常用网络操作类
    java.io.*:数据消息传输包,在网络双方进行数据传递需要使用该包中的类
    在这里插入图片描述

URL及应用

tips:
至于输入输出参考内存:写进来的都是写入流,出去的就是输出流

  1. 常用构造方法:URL(String url)
    常用方法:InputStream openStream() 打开当前URL连接的输入流
    URLConnection openConnection() 建立URL网络连接
    在这里插入图片描述
  2. URLConnection类:应用程序和URL之间的通信链接,用于读取和写入此URL引用的资源
    对象建立方法:
    (1)通过URL对象的openConnection()方法创建
    (2)使用构造方法:URLConnection(URL url)
    在这里插入图片描述
    获得当前连接输入/输出流对象:getInputStream(), getOutputStream()

举一个栗子来感觉一下用法吧:

url = new URL("http://");
// 打开连接
URLConnection conn = url.openConnection();
// 得到输入流
InputStream is = conn.getInputStream();
// 关于IO流的用法和写法一定要熟悉
OutputStream os = new FileOutputStream("d:\\baidu.png");

byte[] buffer = new byte[2048];
int length = 0;

while (-1 != (length = is.read(buffer, 0, buffer.length))) {
os.write(buffer, 0, length);
}
is.close();
os.close();
  1. HttpURLConnection类:特定支持HTTP协议的URLConnection
    抽象类,不能直接实例化对象
    对象建立方法:
    (1)通过URL对象的openConnection()方法创建,强制转换为目标对象
    (2)使用构造方法:HttpURLConnection(URL url)

    常用方法:(1)从URLConnection类继承的方法 (2)针对HTTP请求响应消息的特定方法,此处略

String sUrl = "http://pic42.nipic.com/20140608/12504116_194242259000_2.jpg";
URL url = new URL(sUrl);	// 创建URL对象
InputStream in = url.openStream();	// 获得网络输入流
// 创建文件输出流
FileOutputStream out = new FileOutputStream(“cat.jpg");
int b;
while ((b = in.read()) != -1) {
	out.write(b);		// 写入文件
}
// 关闭输入输出流
out.close();    in.close();

举例:获取服务器HTTP响应消息(消息头和消息主体)

URL url = new URL(rootUrl);	//  创建Url对象
// 得到URLConnection连接对象
URLConnection conn = url.openConnection();
HttpURLConnection hc = (HttpURLConnection) conn;
// 获得响应消息头
conn.getContentType();
conn.getContentLength();
conn.getContentEncoding();
// 获得HTTP消息状态码
hc.getResponseCode();
hc.getResponseMessage();
// 获得HTTP响应消息主体
hc.getContent();

基于套接字的Java网络编程

  1. 客户端与服务器建立连接后,连接两端会建立一个虚拟“线缆”,在网络编程中称之为Socket(套接字); 其后在网络两端传输数据都是通过Socket进行的。
    (1)Socket借助于IP地址和端口号,对应某一台主机中的某一个应用程序
    (2)Socket的主要作用:维护网络连接、在网络双方传输数据

  2. Socket类:客户端套接字类。实现客户端向服务器发送数据、接收服务器数据等功能;实现服务器端向客户端发送数据、接收客户端数据等功能
    构造方法:
    Socket(InetAddress address, int port);
    Socket(String host, int port);

  3. 客户端一般编写步骤:(1)连接服务器端 (2)数据传输 (3)关闭连接,释放资源
    服务器端一般编写步骤:(1)创建服务器端ServerSocket对象 (2)通过accept()方法获取Socket对象 (连接)(3)数据传输 (4)释放资源
    示例1:客户端与服务器端的单次通信,客户端发,服务器收

    注意运行时,应先运行服务器端

import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

public class client1_demo1_xxx {

	public static void main(String[] args) throws UnknownHostException, IOException {
//1.连接到服务器端
		Socket socket = new Socket("127.01.01", 9999);

//2.数据传输向服务器发送数据
		OutputStream os = socket.getOutputStream();
		String content = "你好,我是客户端";
		os.write(content.getBytes());
//3.关闭连接,释放资源
		os.close();
		socket.close();
	}
}
/*
1.getBytes()方法得到一个操作系统默认的编码格式的字节数组
2.可以通过new String(byte[], decode)使用指定的编码decode来将byte[]解析成字符串
String s = new String(b_utf8, "UTF-8");
 */

import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
/*
 * 客户端与服务器端的单次通信,客户端发,服务器收
 * */
public class server1_demo1_xxx {

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
//		1.创建服务器端ServerSocket对象
		ServerSocket server = new ServerSocket(9999);
		System.out.println("等待连接");
		
//		2.通过accept()获取Socket对象
		Socket socket = server.accept();
		System.out.println("连接成功");
		
//		3.数据传输
//		接受客户端的数据
		InputStream is;	
		is = socket.getInputStream();
		byte[] result = new byte[1024];
		is.read(result);
		String s1 = new String(result);
		System.out.println(s1);
//		4.释放资源
		is.close();
		socket.close();
		server.close();
	}
}

示例2:客户端与服务器端的单次双向通信

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
/*
 * 客户端与服务器端的单次双向通信
 * flush()强制把数据输出,清空缓存区
 * */
public class client2_demo2_xxx {

	public static void main(String[] args) throws UnknownHostException, IOException {
		Socket socket = new Socket("127.01.01", 9999);
		OutputStream os = socket.getOutputStream();
		//向服务器发送数据
		String content = "你好,我是客户端";
		os.write(content.getBytes());
		os.flush();
		//收到服务器的数据
		InputStream is = socket.getInputStream();
		byte[] b = new byte[1024];
		is.read(b);
		System.out.println(new String(b));
		
		os.close();
		socket.close();
	}
}

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class server2_demo2_xxx {

	public static void main(String[] args) throws IOException {
//		1.创建服务器端ServerSocket对象
		ServerSocket server = new ServerSocket(9999);
		System.out.println("等待连接");
		
//		2.通过accept()获取Socket对象
		Socket socket = server.accept();
		System.out.println("连接成功");
		
//		3.数据传输
//		接受客户端的数据
		InputStream is;	
		is = socket.getInputStream();
		byte[] result = new byte[1024];
		is.read(result);
		String s1 = new String(result);
		System.out.println(s1);
		
//		向客户端发送数据
		OutputStream oStream = socket.getOutputStream();
		oStream.write(new String("我是服务器,我收到你的信息了").getBytes());
		oStream.flush();
		is.close();
		socket.close();
		server.close();
	}
}

示例3:客户端先发后收,服务器:先收后发

import java.io.DataInputStream;
import java.io.DataOutput;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
/*
 * 客户端先发后收,服务器:先收后发
 * */
public class client3_demo3_xxx {

	public static void main(String[] args) throws UnknownHostException, IOException {
		// TODO Auto-generated method stub
		Socket socket = new Socket("127.01.01", 9999);
		OutputStream os = socket.getOutputStream();
		String content = "你好,我是客户端";
		DataOutputStream dos = new DataOutputStream(os);
		dos.writeUTF(content);
		dos.flush();
		
		//收到服务器的数据
		InputStream is = socket.getInputStream();
		byte[] b = new byte[1024];
		is.read(b);
		System.out.println(new String(b));
		
		os.close();
		socket.close();
	}
}
/*
 * DataOutputStream数据输出流允许将引用程序将基本Java数据类型写到基础输出流中
 * readUTF()---从数据输入流中读取用UTF-8格式编码的UniCode字符格式的字符串.
 */

import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.zip.DeflaterInputStream;

public class server3_demo3_xxx {

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
//		1.创建服务器端ServerSocket对象
		ServerSocket server = new ServerSocket(9999);
		System.out.println("等待连接");
		
//		2.通过accept()获取Socket对象
		Socket socket = server.accept();
		System.out.println("连接成功");
		
//		3.数据传输
		InputStream is = socket.getInputStream();
		DataInputStream dis = new DataInputStream(is);
		String s1 = dis.readUTF();
		System.out.println(s1);
		
//		向客户端发送数据
		OutputStream oStream = socket.getOutputStream();
		oStream.write(new String("我是服务器,我收到你的信息了").getBytes());
		oStream.flush();
		is.close();
		socket.close();
		server.close();
	}

}

示例4:客户端与服务器的多次双向通信

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
/**
 * 客户端与服务器的多次双向通信
 */
public class Client1 {
	public static void main(String[] args) throws Exception {
//		1、连接服务器10.7.90.94
		Socket socket=new Socket("127.0.0.1", 6666);
		
//		2、数据传输
//		向服务器发送数据
		OutputStream os=socket.getOutputStream();
		String content="你好,我是客户端1";
		os.write(content.getBytes());
		os.flush();
		
//		收到服务器的数据
		InputStream is=socket.getInputStream();
		byte[] b=new byte[1024];
		is.read(b);
		System.out.println(new String(b));
		
//		3、关闭连接,释放资源
		os.close();
		socket.close();		
	}
}


import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
/**
 * 客户端与服务器的多次双向通信
 */
public class Client2 {
	public static void main(String[] args) throws Exception {
//		1、连接服务器:10.7.90.94
		Socket socket=new Socket("127.0.0.1", 6666);
//		2、数据传输
//		向服务器发送数据
		OutputStream os=socket.getOutputStream();
		String content="exit";
		os.write(content.getBytes());
		os.flush();
//		收到服务器的数据
		InputStream is=socket.getInputStream();
		byte[] b=new byte[1024];
		is.read(b);
		System.out.println(new String(b));
//		3、关闭连接,释放资源
		os.close();
		socket.close();
				
	}

}



import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class Server1 {
	public static void main(String[] args) throws Exception {
//		1、创建ServerSocket对象,启动服务器
		ServerSocket server = new ServerSocket(6666);
		System.out.println("等待连接");

		InputStream is;
		OutputStream os;

		int i = 0;
		while (true) {
//			i++;
//			if (i == 68) {
//				break;
//			}
//			2、等待客户端连接,处于阻塞
			Socket socket = server.accept();
			System.out.println("连接成功");
//			3、数据传输
//			接收数据
			is = socket.getInputStream();
			byte[] result = new byte[1024];
			is.read(result);
			String s1 = new String(result, "UTF-8");
			System.out.println(s1);

			// 发送数据
			os = socket.getOutputStream();
			os.write(new String("我是服务器端").getBytes());
			os.flush();

			is.close();
			os.close();
			socket.close();
			if (s1.startsWith("exit")) {
				break;
			}
		}
//4、关闭连接
		server.close();
	}
}

实例5: 实现服务器端多线程

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
/**
 * 实现服务器端多线程
 */
public class Client1 {
	public static void main(String[] args) throws Exception {

		Socket socket=new Socket("127.0.0.1", 8888);

		OutputStream os=socket.getOutputStream();
		String content="我是客户端1";
		os.write(content.getBytes());
		os.flush();
		
		Thread.sleep(5000);
		
		InputStream is=socket.getInputStream();
		byte[] b=new byte[1024];
		is.read(b);
		System.out.println(new String(b));
		os.close();
		socket.close();
				
	}

}

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
/**
 * 实现服务器端多线程
 */
public class Client2 {
	public static void main(String[] args) throws Exception {

		Socket socket=new Socket("127.0.0.1", 8888);

		OutputStream os=socket.getOutputStream();
		String content="我是客户端2";
		os.write(content.getBytes());
		os.flush();
		
		Thread.sleep(5000);
		
		InputStream is=socket.getInputStream();
		byte[] b=new byte[1024];
		is.read(b);
		System.out.println(new String(b));
		os.close();
		socket.close();	
	}
}

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

class ServerTread extends Thread {
	private Socket socket;

	public ServerTread(Socket socket) {
		this.socket = socket;
	}

	@Override
	public void run() {

		InputStream is;
		OutputStream os;
		try {
			System.out.println(this.getName());
			is = socket.getInputStream();
			byte[] result = new byte[1024];
			is.read(result);
			String s1 = new String(result, "UTF-8");
			System.out.println(s1);

			os = socket.getOutputStream();
			os.write(new String("我是服务器端").getBytes());
			os.flush();
			socket.close();

		} catch (Exception e) {
			e.printStackTrace();
		}

	}

}

public class Server {
	public static void main(String[] args) throws Exception {
		ServerSocket server = new ServerSocket(8888);
		int i = 0;
		while (true) {
			System.out.println("等待监听");
			Socket socket = server.accept();
			System.out.println("我是服务器端");
			i++;
			if (i == 5) {
				break;
			}
			new ServerTread(socket).start();

		}
		server.close();
	}
}

实例六:练习:实现客户端键盘多次输入,服务器端接收并打印,带缓冲的字符流+循环输入,如果输入以exit开头的内容,退出

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;

/**
 * 实现客户端键盘多次输入,服务器端接收并打印,带缓冲的字符流+循环输入,如果输入exit,退出
 */
public class Client1 {
	public static void main(String[] args) throws Exception {
//		Scanner对象实现键盘输入
		Scanner scanner = new Scanner(System.in);
		Socket socket = new Socket("127.0.0.1", 9000);

		OutputStream os = socket.getOutputStream();
		BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os));
		//System.out.println("请输入用户名:");
		while (true) {
			String input = scanner.nextLine();
			
//			带缓冲的字符流,使用低级的字节流来构建
			writer.write(input);
			input = input + '\n';
			writer.flush();
			if(input.startsWith("exit")) {
				break;
			}	
		}
		writer.close();
		socket.close();
	}
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {
	public static void main(String[] args) throws Exception {
		ServerSocket server=new ServerSocket(9000);
		System.out.println("等待连接");
		Socket socket=server.accept();
		System.out.println("连接成功");
		InputStream is=socket.getInputStream();
		BufferedReader reader=new BufferedReader(new InputStreamReader(is));
		while(true) {
			String result = reader.readLine();
			if(result == null) {
				break;
			}
			System.out.println("你的输入是:"+result);
		}
		is.close();
		socket.close();
		server.close();
	}
}

其他知识

  1. InetAddress类
import java.net.InetAddress;
import java.net.UnknownHostException;

public class InetAddressDemo {
	
	public static void main(String[] args) throws Exception {
		InetAddress address=InetAddress.getLocalHost();
		System.out.println(address.getHostAddress());//返回文本显示中的IP地址字符串。
		System.out.println(address.getHostName());//获取此IP地址的主机名。
	}
}

  1. 流的简单应用:从网上下载一个图片
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;


public class Demo1 {
	public static void main(String[] args) throws IOException {
		String url_str="https://www.baidu.com/img/flexible/logo/pc/result.png";
		URL url=new URL(url_str);
//		URLConnection conn=url.openConnection();
//		InputStream is=conn.getInputStream();//����ڴ�
		
		InputStream is=url.openConnection().getInputStream();
		
		OutputStream os=new FileOutputStream("d:\\demo\\a20220222.png");
		int n=-1;
		while((n=is.read())!=-1) {
			os.write(n);
		}
		is.close();
		os.close();
		System.out.println("下载成功");
	}
}

基于UDP网络编程

上述代码均为基于TCO传输协议的的网络编程。此处介绍UDP相关知识

  1. TCP与UDP连接的区别:
    在这里插入图片描述

  2. UDP传输协议通过数据包方式向服务器发送数据,在数据包中包含服务器的IP信息、端口信息等内容。

  3. DatagramSocket类:客户端/服务器端网络Socket端口对象
    构造方法:
    (1)DatagramSocket(); // 创建一个空的Socket对象
    (2)DatagramSocket(int port); // 创建指定监听端口的Socket对象
    常用方法:
    (1)void send(DatagramPacket p); // 发送数据报文
    (2)void receive(DatagramPacket p); // 接收数据报文

  4. DatagramPacket类:数据报文对象
    构造方法:

DatagramPacketbyte[]  buf, int len);  
// 用空数组创建对象,用来接收数据
DatagramPacketbyte[] buf, int offset, int len); 
 // 接收数据的特定部分
DatagramPacketbyte[] buf, int len, InetAddress addr, int port);  
// 包含数据的数组创建对象,用来发送数据,同时指明数据目的地和目标端口号
DatagramPacketbyte[] buf, int offset, int len, InetAddress addr, int port);  
// 发送数据的指定部分
  1. 客户端一般编写步骤:(1)创建DatagramSocket对象 (2)封装请求数据 (3)创建DatagramPacket对象 (4)发送请求
    服务器端一般编写步骤:(1)创建DatagramSocket对象,监听特定端口 (2)创建DatagramPacket对象(空缓冲区) (3)封装服务器响应数据,创建DatagramPacket对象 (4)发送服务器响应给指定客户端

示例1:单向发送、接收

package udp1__xxx;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;

//发送端
public class Sender {

	public static void main(String[] args) throws IOException {
//		1.创建DategramSocket对象,不需要指定端口
		DatagramSocket socket = new DatagramSocket();
//		2.【数据报中只允许字节数组】, 准备字节数组
		byte[] input = "hellow.sever".getBytes();
//		3.创建DatagramPacket对象,需要指定接收方的ip,端口号
		DatagramPacket packet = new DatagramPacket(input, input.length, InetAddress.getByName("127.0.0.1"), 8000);
//		4.发送数据
		socket.send(packet);
//		5.关闭连接
		socket.close();
	}
}

package udp1__xxx;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
/*
 * 单向发送、接收
 * */
public class Recevier {

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
//		1.接收方、创建DatagramSocket对象,需要指定端口号
		DatagramSocket socket = new DatagramSocket(8000);
		byte[] data = new byte[1024];
//		2.DatagramPacket
		DatagramPacket packet = new DatagramPacket(data, data.length);
		System.out.println("等待接收");
//		3.阻塞式接受
		socket.receive(packet);
		System.out.println("接收完成");
//		4.分析数据
		byte[] result = packet.getData();
		System.out.println(new String(result));
//		5.关闭Socket
		socket.close();
	}

}

示例2:学生端先发送,后接收; 教师端先接受,后发送

package udp2_xxx;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
/*
 * 学生端先发送,后接收
 * 教师端先接受,后发送
 * */
public class Student {

	public static void main(String[] args) throws IOException {
//		1.创建DategramSocket对象
		DatagramSocket socket = new DatagramSocket(9000);
//		2.【数据报中只允许字节数组】, 准备字节数组
		byte[] input = "hellow.imstudent".getBytes();
//		3.创建DatagramPacket对象,需要指定接收方的ip,端口号
		DatagramPacket packet = new DatagramPacket(input, input.length, InetAddress.getByName("127.0.01"), 8000);
//		4.发送数据
		socket.send(packet);
		
		byte[] data = new byte[1024];
//		2.DatagramPacket
		DatagramPacket packet2 = new DatagramPacket(data, data.length);
		System.out.println("等待接收");
//		3.阻塞式接受
		socket.receive(packet2);
		System.out.println("接收完成");
//		4.分析数据
		byte[] result = packet2.getData();
		System.out.println(new String(result));
//		5.关闭Socket
		socket.close();
	}

}

package udp2_xxx;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;

public class teacher {

	public static void main(String[] args) throws IOException {
		
//		1.接收方、创建DatagramSocket对象,需要指定端口号
		DatagramSocket socket = new DatagramSocket(8000);
		byte[] data = new byte[1024];
//		2.DatagramPacket
		DatagramPacket packet = new DatagramPacket(data, data.length);
		System.out.println("等待接收");
//		3.阻塞式接受
		socket.receive(packet);
		System.out.println("接收完成");
//		4.分析数据
		byte[] result = packet.getData();
		System.out.println(new String(result));
//		5.关闭Socket
		
		byte[] input = "hellow.imteacher".getBytes();
//		3.创建DatagramPacket对象,需要指定接收方的ip,端口号
		DatagramPacket packet2 = new DatagramPacket(input, input.length, InetAddress.getByName("127.0.01"), 9000);
//		4.发送数据
		socket.send(packet2);
//		5.关闭连接
		socket.close();
	}

}

示例3:键盘输入多次向教师端发送数据

package udp3_xxx;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.zip.InflaterInputStream;
/*
 * 键盘输入多次发送
 * */
public class student {

	public static void main(String[] args) throws IOException {
//		1.创建DategramSocket对象
		DatagramSocket socket = new DatagramSocket(9000);
//		2. 准备字节数组【数据报中只允许字节数组】
		System.out.println("你的名字:");
		
		
		while(true) {
			BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
			String result = br.readLine();
			byte[] input = result.getBytes();
//			3.创建DatagramPacket对象,需要指定接收方的ip,端口号
			DatagramPacket packet = new DatagramPacket
					(input, input.length, InetAddress.getByName("127.0.01"), 8000);
//			4.发送数据
			socket.send(packet);
			if(result.equals("bye")) {
				break;
			}
		}
		
		byte[] data = new byte[1024];
//		2.DatagramPacket
		DatagramPacket packet2 = new DatagramPacket(data, data.length);
		System.out.println("等待接收");
//		3.阻塞式接受
		socket.receive(packet2);
		System.out.println("接收完成");
//		4.分析数据
		byte[] result = packet2.getData();
		System.out.println(new String(result));
//		5.关闭Socket
		socket.close();
	}

}

package udp3_xxx;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;

public class teacher {

	public static void main(String[] args) throws IOException {
//		1.接收方、创建DatagramSocket对象,需要指定端口号
		DatagramSocket socket = new DatagramSocket(8000);
		byte[] data = new byte[1024];
//		2.DatagramPacket
		while(true) {
			DatagramPacket packet = new DatagramPacket(data, data.length);
			System.out.println("等待接收");
//			3.阻塞式接受
			socket.receive(packet);
			System.out.println("接收完成");
//			4.分析数据
			byte[] result = packet.getData();
			String str = new String(result);
			System.out.println(str);
			if(str.equals("")) {
				break;
			}
		}
		
		byte[] input = "hellow.imteacher".getBytes();
//		3.创建DatagramPacket对象,需要指定接收方的ip,端口号
		DatagramPacket packet2 = new DatagramPacket(input, input.length, InetAddress.getByName("127.0.01"), 9000);
//		4.发送数据
		socket.send(packet2);
//		5.关闭连接
		socket.close();

	}

}

示例4:学生端、老师端,均启动两个子线程

package udp3_xxx;

import java.net.SocketException;

public class teachers {
	public static void main(String[] args) throws SocketException {
		new Thread(new ChatRecevier(9000, "小孩说")).start();
		new Thread(new ChatSender("127.0.0.1", 8000)).start();
	}
}

package udp3_xxx;

import java.net.SocketException;
/*
 * 学生端、老师,都启动两个子线程
 * */
public class students {

	public static void main(String[] args) throws SocketException {
		new Thread(new ChatRecevier(8000, "老师说")).start();
		new Thread(new ChatSender("127.0.0.1", 9000)).start();
		
	}

}

package udp3_xxx;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;

public class ChatSender implements Runnable{
	DatagramSocket socket;
	String ip;
	int port;
	BufferedReader br;
	public ChatSender(String ip, int port) throws SocketException {
		socket = new DatagramSocket();
		this.ip = ip;
		this.port = port;
		this.br = new BufferedReader(new InputStreamReader(System.in));
	}
	
	@Override
	public void run() {
		while(true) {
			String result = null;
			try {
				result = br.readLine();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			byte[] input = result.getBytes();
//			3.创建DatagramPacket对象,需要指定接收方的ip,端口号
			DatagramPacket packet = null;
			try {
				packet = new DatagramPacket
						(input, input.length, InetAddress.getByName(this.ip), this.port);
			} catch (UnknownHostException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
//			4.发送数据
			try {
				socket.send(packet);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			if(result.startsWith("bye")) {
				break;
			}
		}
		
	}
	
}

package udp3_xxx;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

public class ChatRecevier implements Runnable {
	DatagramSocket socket;
	String form;

	public ChatRecevier(int port, String form) throws SocketException {
		socket = new DatagramSocket(port);
		this.form = form;
	}

	public void run() {
		while (true) {
			byte[] data = new byte[1024];
			DatagramPacket packet = new DatagramPacket(data, data.length);
			try {
				socket.receive(packet);
				byte[] result = packet.getData();
				String strs = new String(result);
				System.out.println(form + strs);
				if (strs.startsWith("bye")) {
					break;
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Xuhx&

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值