之前我将new DatagramSocket放入了while循环中,报了java.net.BindException: Address already in use: Cannot bind,才知道不能在while中连续创建新的DatagramSocket对象。
2.7 创建客户端类
package com.linuxidc; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; public class UDPClient { public static void main(String[] args) throws IOException { //定义服务器的地址,端口号,数据 InetAddress address = InetAddress.getByName("localhost"); int port = 8800; byte[] data = "用户名:admin;密码:123".getBytes();//将字符串转换为字节数组 //创建数据报 DatagramPacket packet = new DatagramPacket(data, data.length, address, port); //创建DatagramSocket,实现数据发送和接收 DatagramSocket socket = new DatagramSocket(); //向服务器端发送数据报 socket.send(packet); //接收服务器响应数据 byte[] data2 = new byte[1024]; DatagramPacket packet2 = new DatagramPacket(data2, data2.length); socket.receive(packet2); String info = new String(data2, 0, packet2.getLength()); System.out.println("我是客户端,服务器说:"+info); socket.close(); } }
2.8 先运行服务器端,在运行客户端
2.9 修改客户端信息,再次运行客户端
服务器控制台:服务器端一直在循环等待接收客户端的数据。
三. 总结
这两个例子只是简单的实现了基于TCP和UDP的socket编程,其中像多线程的优先级等都暂且没做考虑,不过依然要强调一下,服务器与多个客户端进行通信,因为是死循环,不设置多线程优先级,可能会导致运行时速度非常慢,优先级的范围1-10,默认为5,我们可以适当降低线程的优先级,比如thread.setPriority(4);
对于同一个socket,如果关闭了输出流比如(pw.close()),则与该输出流关联的socket也会关闭,所以一般不需要关闭输出流,当关闭socket的时候,输出流也会关闭,直接关闭socket就行。
在使用TCP通信传输信息时,更多是使用对象的形式来传输,可以使用ObjectOutputStream对象序列化流来传递对象,比如ObjectOutputStream os = new ObjectOutputStream(socket.getOutputStream());User user = new User("admin","123"); os.writeObject(user);
希望这篇文章能让你有所获,麻烦点赞或关注我,谢谢观看!