测试方向基础-网络编程

网络编程

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

网络编程:在网络通信协议下,实现网络互连的不同计算机上运行的程序间可以进行数据交换

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wfOkFE1U-1647868064146)(C:\Users\yyc\AppData\Roaming\Typora\typora-user-images\image-20220321185708421.png)]

IP地址、域名、端口、URL

  • IP地址:为了准确地定位网络上的目标主机,网络中的每个设备都会有一个唯一的数字表示,即网络的IP地址。

    static InetAddress getByName(String host):host) 确定主机名称的IP地址。主机名称可以是机器名称,也可以是IP地址.

    public class InetAddressDemo {
    public static void main(String[] args) throws UnknownHostException {
    //InetAddress address = InetAddress.getByName("itheima");
    InetAddress address = InetAddress.getByName("192.168.1.66");
    //public String getHostName():获取此IP地址的主机名
    String name = address.getHostName();
    //public String getHostAddress():返回文本显示中的IP地址字符串
    String ip = address.getHostAddress();
    System.out.println("主机名:" + name);
    System.out.println("IP地址:" + ip);
    }
    }
    
  • 域名:由于IP地址不宜记忆,引入网络域名来确认IP地址。

  • 端口:IP地址可以精确地确定一台主句,但是这台主机上可能运行着多个程序;可以借助主机端口精确地确定客户访问的是这台主机中的哪一个应用程序。【1~1024之内的端口号被系统占用,不可以用】

  • URL:网络上的资源

TCP/UDP协议

网络传输的过程中数据的传递有两种最常见的形式:

  • TCP传输控制协议:是一种面向连接的、可靠的、基于字节流传输层通信协议,由于这种面向连接的特性, TCP协议可以保证传输数据的安全,所以应用十分广泛。例如上传文件、下载文件、浏览网页等

    • 三次握手:

      三次握手:TCP协议中,在发送数据的准备阶段,客户端与服务器之间的三次交互,以保证连接的可靠
      第一次握手,客户端向服务器端发出连接请求,等待服务器确认
      第二次握手,服务器端向客户端回送一个响应,通知客户端收到了连接请求
      第三次握手,客户端再次向服务器端发送确认信息,确认连接
      
  • UDP用户数据报协议是一种无连接的传输协议,提供面向事务的简单不可靠信息传送服务。

    • 无需建立网络双方连接,直接发送数据包(包含目的地址信息),可能会因为网络问题导致数据传输失败等问题,但是传输速度很块,常用于局域网传输数据。

常见开发模型C/S|B/S

  • 客户端/服务器模式(C/S模式):对于不同的服务端程序建立不同的客户端程序
    • 在网络编程中,C/S模式应用程序的开发,需要同时开发客户端应用程序和服务器端应用程序
  • 浏览器/服务器模式(B/S模式):对于不同的服务器使用统一的”客户端“(即浏览器)即可
    • B/S模式应用程序的开发,由于客户端使用浏览器访问,服务器端应用程序本质上属于Web应用程序;浏览器和服务器通信协议采用HTTP协议

URL即应用

在java语言中,提供了一组URL处理类,封装了Socket编程技术的实现细节,用来方便开发人员进行网络连接、网络数据传输等常用的网络任务。

例子:保存网页中的内容:

public class Demo {
    public static void main(String[] args) throws IOException {
        //在百度上找到想复制的图片,右键复制图片链接
        String url_str="https://files.codelife.cc/itab/search/baidu.svg";
        //创建URL对象
        URL url=new URL(url_str);
        //获得网络输入流
//        InputStream is=url.openConnection().getInputStream();
        InputStream is=url.openStream();
        //创建文件输出流保存数据
        OutputStream os=new FileOutputStream("E:\\yyyc.svg");
        int len;
        while((len=is.read())!=-1){
            //写入文件
            os.write(len);
        }
        is.close();
        os.close();
        System.out.println("下载完成");
    }

TCP Socket ServerSocket

  • 客户端Socket应用程序锁做的工作主要有3步:

    1.与服务器端建立连接(通过IP和端口号确定主机上的程序)
    Socket  client  =  new Socket(“localhost”,  80)
    2.向服务器端发送数据,接收服务器端数据
    向服务器端发送数据:os  =  client.getOutputStream()
    接收服务器端数据:is  =  client.getInputStream()
    3.关闭Socket连接
    client.close()
    
  • 服务器端所作的主要工作有4步:

    1.监听特定端口
    ServerSocket  server  =  new  ServerSocket(8888)
    2.接收客户端连接
    Socket  client  =  server.accept()
    3.接收客户端请求,向客户端发送响应
    接收客户端请求数据:is  =  client.getInputStream()
    向客户端响应数据:os  =  client.getOutputStream()
    4.关闭连接
    关闭服务器端:server.close()
    

UDP DatagramSocket

  • DatagramSocket类:客户端/服务端网络Socket端口对象

    构造方法:
    DatagramSocket();   // 创建一个空的Socket对象
    DatagramSocket(int  port);  // 创建指定监听端口的Socket对象
    常用方法:
    void  send(DatagramPacket  p);  // 发送数据报文
    void  receive(DatagramPacket  p);  // 接收数据报文
    
    
  • DatagramPacket类:数据报文对象

     // 包含数据的数组创建对象,用来发送数据,同时指明数据目的地和目标端口号
    DatagramPacket(byte[] buf, int len, InetAddress addr, int port); 
    
  • 客户端4步

    1.创建DatagramSocket对象
    2.封装请求数据,
    3.创建DatagramPacket对象
    4.发送请求
    
  • 服务器端5步

    1.创建DatagramSocket对象,监听特定端口
    2.创建DatagramPacket对象(空缓冲区)
    3.接收客户端请求
    4.封装服务器响应数据,创建DatagramPacket对象
    5.发送服务器响应给指定客户端
    

TCP经典练习:

场景1:实现客户端,服务器端单次双向数据传输

​ 客户端发送,服务器端接收

​ 服务器端发送,客户端接收

案例需求
客户端:发送数据,接受服务器反馈
服务器:收到消息后给出反馈
案例分析
客户端创建对象,使用输出流输出数据
服务端创建对象,使用输入流接受数据
服务端使用输出流给出反馈数据
客户端使用输入流接受反馈数据
public class ServerDemo {
public static void main(String[] args) throws IOException {
//创建服务器端的Socket对象(ServerSocket)
ServerSocket ss = new ServerSocket(10000);
//监听客户端连接,返回一个Socket对象
Socket s = ss.accept();
//获取输入流,读数据,并把数据显示在控制台
InputStream is = s.getInputStream();
byte[] bys = new byte[1024];
int len = is.read(bys);
String data = new String(bys, 0, len);
System.out.println("服务器:" + data);
//给出反馈
OutputStream os = s.getOutputStream();
os.write("数据已经收到".getBytes());
//释放资源
// s.close();
ss.close();
}
}
public class ClientDemo {
public static void main(String[] args) throws IOException {
3.4TCP通信程序练习【应用】
案例需求
客户端:数据来自于键盘录入, 直到输入的数据是886,发送数据结束
服务端:接收到数据在控制台输出
案例分析
客户端创建对象,使用键盘录入循环接受数据,接受一行发送一行,直到键盘录入886为止
服务端创建对象,使用输入流按行循环接受数据,直到接受到null为止
代码实现
//创建客户端的Socket对象(Socket)
Socket s = new Socket("192.168.1.66", 10000);
//获取输出流,写数据
OutputStream os = s.getOutputStream();
os.write("hello,tcp,我来了".getBytes());
//接收服务器反馈
InputStream is = s.getInputStream();
byte[] bys = new byte[1024];
int len = is.read(bys);
String data = new String(bys, 0, len);
System.out.println("客户端:" + data);
//释放资源
// is.close();
// os.close();
s.close();
}
}

场景2:客户端多次输入服务器循环接收

1.

案例需求
客户端:数据来自于键盘录入, 直到输入的数据是886,发送数据结束
服务端:接收到数据在控制台输出
案例分析
客户端创建对象,使用键盘录入循环接受数据,接受一行发送一行,直到键盘录入886为止
服务端创建对象,使用输入流按行循环接受数据,直到接受到null为止

public class ClientDemo {
public static void main(String[] args) throws IOException {
//创建客户端Socket对象
Socket s = new Socket("192.168.1.66",10000);
//数据来自于键盘录入,直到输入的数据是886,发送数据结束
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
//封装输出流对象
BufferedWriter bw = new BufferedWriter(new
OutputStreamWriter(s.getOutputStream()));
String line;
while ((line=br.readLine())!=null) {
if("886".equals(line)) {
break;
}
//获取输出流对象
bw.write(line);
bw.newLine();
3.5TCP通信程序练习【应用】
案例需求
客户端:数据来自于键盘录入,直到输入的数据是886,发送数据结束
服务端:接受到的数据写入文本文件中
案例分析
客户端创建对象,使用键盘录入循环接受数据,接受一行发送一行,直到键盘录入886为止
服务端创建对象,创建输出流对象指向文件,每接受一行数据后使用输出流输出到文件中,直到接受到
null为止
代码实现
bw.flush();
}
//释放资源
s.close();
}
}
public class ServerDemo {
public static void main(String[] args) throws IOException {
//创建服务器Socket对象
ServerSocket ss = new ServerSocket(10000);
//监听客户端的连接,返回一个对应的Socket对象
Socket s = ss.accept();
//获取输入流
BufferedReader br = new BufferedReader(new
InputStreamReader(s.getInputStream()));
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
//释放资源
ss.close();
}
}

2.

案例需求
客户端:数据来自于键盘录入,直到输入的数据是886,发送数据结束
服务端:接受到的数据写入文本文件中
案例分析
客户端创建对象,使用键盘录入循环接受数据,接受一行发送一行,直到键盘录入886为止
服务端创建对象,创建输出流对象指向文件,每接受一行数据后使用输出流输出到文件中,直到接受到
null为止

ublic class ClientDemo {
public static void main(String[] args) throws IOException {
//创建客户端Socket对象
Socket s = new Socket("192.168.1.66",10000);
//数据来自于键盘录入,直到输入的数据是886,发送数据结束
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
//封装输出流对象
BufferedWriter bw = new BufferedWriter(new
OutputStreamWriter(s.getOutputStream()));
String line;
3.6TCP通信程序练习【应用】
案例需求
客户端:数据来自于文本文件
服务器:接收到的数据写入文本文件
案例分析
创建客户端,创建输入流对象指向文件,从文件循环读取数据,每读取一行就使用输出流给服务器输出
一行
创建服务端,创建输出流对象指向文件,从客户端接受数据,每接受一行就给文件中输出一行
代码实现
while ((line=br.readLine())!=null) {
if("886".equals(line)) {
break;
}
bw.write(line);
bw.newLine();
bw.flush();
}
//释放资源
s.close();
}
}
public class ServerDemo {
public static void main(String[] args) throws IOException {
//创建服务器Socket对象
ServerSocket ss = new ServerSocket(10000);
//监听客户端连接,返回一个对应的Socket对象
Socket s = ss.accept();
//接收数据
BufferedReader br = new BufferedReader(new
InputStreamReader(s.getInputStream()));
//把数据写入文本文件
BufferedWriter bw = new BufferedWriter(new FileWriter("myNet\\s.txt"));
String line;
while ((line=br.readLine())!=null) {
bw.write(line);
bw.newLine();
bw.flush();
}
//释放资源
bw.close();
ss.close();
}
}

3.

案例需求
客户端:数据来自于文本文件
服务器:接收到的数据写入文本文件
案例分析
创建客户端,创建输入流对象指向文件,从文件循环读取数据,每读取一行就使用输出流给服务器输出
一行
创建服务端,创建输出流对象指向文件,从客户端接受数据,每接受一行就给文件中输出一行
public class ClientDemo {
3.7TCP通信程序练习【应用】
public static void main(String[] args) throws IOException {
//创建客户端Socket对象
Socket s = new Socket("192.168.1.66",10000);
//封装文本文件的数据
BufferedReader br = new BufferedReader(new
FileReader("myNet\\InetAddressDemo.java"));
//封装输出流写数据
BufferedWriter bw = new BufferedWriter(new
OutputStreamWriter(s.getOutputStream()));
String line;
while ((line=br.readLine())!=null) {
bw.write(line);
bw.newLine();
bw.flush();
}
//释放资源
br.close();
s.close();
}
}
public class ServerDemo {
public static void main(String[] args) throws IOException {
//创建服务器Socket对象
ServerSocket ss = new ServerSocket(10000);
//监听客户端连接,返回一个对应的Socket对象
Socket s = ss.accept();
//接收数据
BufferedReader br = new BufferedReader(new
InputStreamReader(s.getInputStream()));
//把数据写入文本文件
BufferedWriter bw = new BufferedWriter(new FileWriter("myNet\\Copy.java"));
String line;
while ((line=br.readLine())!=null) {
bw.write(line);
bw.newLine();
bw.flush();
}
//释放资源
bw.close();
ss.close();
}
}

4.

案例需求
客户端:数据来自于文本文件,接收服务器反馈
服务器:接收到的数据写入文本文件,给出反馈
案例分析
创建客户端对象,创建输入流对象指向文件,每读入一行数据就给服务器输出一行数据,输出结束后使
用shutdownOutput()方法告知服务端传输结束
创建服务器对象,创建输出流对象指向文件,每接受一行数据就使用输出流输出到文件中,传输结束
后。使用输出流给客户端反馈信息
客户端接受服务端的回馈信息

public class ClientDemo {
public static void main(String[] args) throws IOException {
//创建客户端Socket对象
Socket s = new Socket("192.168.1.66",10000);
//封装文本文件的数据
BufferedReader br = new BufferedReader(new
FileReader("myNet\\InetAddressDemo.java"));
//封装输出流写数据
BufferedWriter bw = new BufferedWriter(new
OutputStreamWriter(s.getOutputStream()));
String line;
while ((line=br.readLine())!=null) {
bw.write(line);
bw.newLine();
bw.flush();
}
//public void shutdownOutput()
s.shutdownOutput();
//接收反馈
BufferedReader brClient = new BufferedReader(new
InputStreamReader(s.getInputStream()));
String data = brClient.readLine(); //等待读取数据
System.out.println("服务器的反馈:" + data);
//释放资源
br.close();
s.close();

场景3:服务器多线程,客户端单线程

​ 主线程:负责等待,创建连接

​ 子线程:传输数据

案例需求
客户端:数据来自于文本文件,接收服务器反馈
服务器:接收到的数据写入文本文件,给出反馈,代码用线程进行封装,为每一个客户端开启一个线程
案例分析
创建客户端对象,创建输入流对象指向文件,每读入一行数据就给服务器输出一行数据,输出结束后使
用shutdownOutput()方法告知服务端传输结束
创建多线程类,在run()方法中读取客户端发送的数据,为了防止文件重名,使用计数器给文件名编号,
接受结束后使用输出流给客户端发送反馈信息。
创建服务端对象,每监听到一个客户端则开启一个新的线程接受数据。
客户端接受服务端的回馈信息
public class ClientDemo {
public static void main(String[] args) throws IOException {
//创建客户端Socket对象
Socket s = new Socket("192.168.1.66",10000);
//封装文本文件的数据
BufferedReader br = new BufferedReader(new
FileReader("myNet\\InetAddressDemo.java"));
//封装输出流写数据
BufferedWriter bw = new BufferedWriter(new
OutputStreamWriter(s.getOutputStream()));
String line;
while ((line=br.readLine())!=null) {
bw.write(line);
bw.newLine();
bw.flush();
}
s.shutdownOutput();
//接收反馈
BufferedReader brClient = new BufferedReader(new
InputStreamReader(s.getInputStream()));
String data = brClient.readLine(); //等待读取数据
System.out.println("服务器的反馈:" + data);
//释放资源
br.close();
s.close();
}
}
public class ServerThread implements Runnable {
private Socket s;
public ServerThread(Socket s) {
this.s = s;
}
@Override
public void run() {
try {
//接收数据写到文本文件
BufferedReader br = new BufferedReader(new
InputStreamReader(s.getInputStream()));
//解决名称冲突问题
int count = 0;
File file = new File("myNet\\Copy["+count+"].java");
while (file.exists()) {
count++;
file = new File("myNet\\Copy["+count+"].java");
}
BufferedWriter bw = new BufferedWriter(new FileWriter(file));
String line;
while ((line=br.readLine())!=null) {
bw.write(line);
bw.newLine();
bw.flush();
}
//给出反馈
BufferedWriter bwServer = new BufferedWriter(new
OutputStreamWriter(s.getOutputStream()));
bwServer.write("文件上传成功");
bwServer.newLine();
bwServer.flush();
//释放资源
s.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public class ServerDemo {
public static void main(String[] args) throws IOException {
//创建服务器Socket对象
ServerSocket ss = new ServerSocket(10000);
while (true) {
//监听客户端连接,返回一个对应的Socket对象
Socket s = ss.accept();
//为每一个客户端开启一个线程
new Thread(new ServerThread(s)).start();
}
}
}

场景4:服务器端多线程,客户端多线程

//客户端,(主线程:发送数据,子线程:接收数据)

class ClientThread extends Thread{
	private Socket socket;
	public ClientThread(Socket socket){
		this.socket =socket;
	}
	@Override
	public void run() {
//		接收数据
		InputStream is;
		try {
			is = this.socket.getInputStream();
			BufferedReader reader=new BufferedReader
					(new InputStreamReader(is));
			String result=reader.readLine();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
	
}
public class Client {
	
	public static void main(String[] args) throws Exception {
//		Scanner对象实现键盘输入
		Scanner scanner = new Scanner(System.in);
		Socket socket = new Socket("127.0.0.1", 8888);

		
//		以下接收数据使用子线程实现
//		InputStream is = socket.getInputStream();
//		BufferedReader reader=new BufferedReader
//				(new InputStreamReader(is));
//		String result=reader.readLine();
		
		new ClientThread(socket).start();
	
//	     发送数据
		OutputStream os = socket.getOutputStream();
		
//		带缓冲的字符流,使用低级的字节流来构建
		BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os));
		System.out.println("请输入用户名:");
		while (true) {
			String input = scanner.nextLine();
			writer.write(input + "\n");
			writer.flush();
			if (input.startsWith("exit")) {
				break;
			}

		}
		
		

		writer.close();
		socket.close();
	}

}

//子线程负责数据传输,主线程负责接受客户端连接
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();
	}

}

UDP经典练习

场景1:单项的发送,接收

//发送端
public class Sender {
	public static void main(String[] args) throws Exception {
//		1、创建DatagramSocket对象,不需要指定端口
		DatagramSocket socket=new DatagramSocket(9000);
//		2、准备字节数组
		byte[] input="hello,Server".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();
	}

}
//接收方
public class Recevier {
	public static void main(String[] args) throws Exception {
//		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:双向的发送,接收

 * 实现双向的数据传输
 * 学生端先发送,后接收
 * 教师端先接收,后发送
public class Student {
	public static void main(String[] args) throws Exception {
//		1、创建DatagramSocket对象,不需要指定端口
		DatagramSocket socket=new DatagramSocket(9000);
//		2、准备字节数组
		byte[] input="我是学生端".getBytes();
//		3、创建DatagramPacket对象,需要指定接收方的ip,端口号
		DatagramPacket packet=new DatagramPacket
				(input, 
				input.length,
				InetAddress.getByName("127.0.0.1"),
				8000);
//		4、发送数据
		socket.send(packet);
		
//		接收数据
		byte[] result=new byte[1024];
		DatagramPacket packet2=new DatagramPacket
				(result, result.length);
		
		socket.receive(packet2);
		byte[] data=packet2.getData();
		System.out.println(new String(data));	
		
//		5、关闭连接
		socket.close();
	}
}

public class Teacher {
	public static void main(String[] args) throws Exception {
//		1、创建DatagramSocket对象,需要指定端口号
		DatagramSocket socket = new DatagramSocket(8000);
		byte[] data = new byte[1024];
//		2、创建DatagramPacket
		DatagramPacket packet1 = new DatagramPacket
				(data, data.length);
		System.out.println("等待接收");
//		3、阻塞式接收
		socket.receive(packet1);//阻塞式接收
		System.out.println("接收完成");
//		4、分析数据
		byte[] result=packet1.getData();
		System.out.println(new String(result));
		
//		发送数据
		
		byte[] input="我是教师端".getBytes();
		DatagramPacket packet2 = new DatagramPacket
				(input,
					input.length,
					InetAddress.getByName("127.0.0.1"),
					9000
					);
		socket.send(packet2);
		
//		5、关闭Socket
		socket.close();

	}
}

场景3:键盘输入的字符串进行发送,发送多次,接收多次,while

案例需求
UDP发送数据:数据来自于键盘录入,直到输入的数据是886,发送数据结束
UDP接收数据:因为接收端不知道发送端什么时候停止发送,故采用死循环接收
public class SendDemo {
public static void main(String[] args) throws IOException {
//创建发送端的Socket对象(DatagramSocket)
DatagramSocket ds = new DatagramSocket();
//自己封装键盘录入数据
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String line;
while ((line = br.readLine()) != null) {
//输入的数据是886,发送数据结束
if ("886".equals(line)) {
break;
}
//创建数据,并把数据打包
byte[] bys = line.getBytes();
DatagramPacket dp = new DatagramPacket(bys, bys.length,
InetAddress.getByName("192.168.1.66"), 12345);
//调用DatagramSocket对象的方法发送数据
ds.send(dp);
}
//关闭发送端
ds.close();
}
}
/*
UDP接收数据:
因为接收端不知道发送端什么时候停止发送,故采用死循环接收
*/
public class ReceiveDemo {
public static void main(String[] args) throws IOException {
//创建接收端的Socket对象(DatagramSocket)
DatagramSocket ds = new DatagramSocket(12345);
while (true) {
//创建一个数据包,用于接收数据
byte[] bys = new byte[1024];
DatagramPacket dp = new DatagramPacket(bys, bys.length);
//调用DatagramSocket对象的方法接收数据
ds.receive(dp);
//解析数据包,并把数据在控制台显示
System.out.println("数据是:" + new String(dp.getData(), 0,
dp.getLength()));
}
//关闭接收端
// ds.close();
}
}

场景4:子线程1负责发送,子线程2负责接收,老师端、学生端都启用了两个子线程

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

	public ChatRecevier(int port,String from) throws Exception {
		socket =new DatagramSocket(port);
		this.from=from;
	}
	@Override
	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 print_str=new String(result);
				System.out.println(from+print_str);
				if(print_str.startsWith("bye")) {
					break;
				}
				
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			
		}
		
		
		
	}

}

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

		

		
		
//		5、关闭连接
		socket.close();
		
		
	}

}

public class Student {
	public static void main(String[] args) throws Exception {
		new Thread(new ChatRecevier(8000, "教师说:")).start();
		new Thread(new ChatSender("127.0.0.1", 9000)).start();
	}

}
public class Teacher {
public static void main(String[] args) throws Exception {
	new Thread(new ChatRecevier(9000, "学生说:")).start();
	new Thread(new ChatSender("127.0.01", 8000)).start();
}
}

场景5:发送其他数据

public class Recevier {
public static void main(String[] args) throws Exception {
	DatagramSocket socket=new DatagramSocket(8000);
	byte[] cache=new byte[1024];
	DatagramPacket packet=new DatagramPacket(cache, cache.length);
	socket.receive(packet);
	
	ByteArrayInputStream bis=
			new ByteArrayInputStream(packet.getData());
	DataInputStream dis=new DataInputStream(bis);
	
	System.out.println(dis.readDouble()); 
	System.out.println(dis.readUTF());
	System.out.println(dis.readInt());
}

}
//发送多种类型的数据
public class Sender {
	public static void main(String[] args) throws IOException {
		DatagramSocket socket=new DatagramSocket();
		
		ByteArrayOutputStream bos=new ByteArrayOutputStream();
		DataOutputStream dos=new DataOutputStream
				(new BufferedOutputStream(bos));
		dos.writeDouble(2.2334);
		dos.writeUTF("hello");
		dos.writeInt(20);
		dos.flush();
		
		byte[] data=bos.toByteArray();
		
		DatagramPacket packet=new DatagramPacket
				(data, data.length,
						InetAddress.getByName("127.0.0.1")
						,8000);
		socket.send(packet);
		
	
	}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值