问题:编写一个网络应用程序,有客户端和服务端,客户端向服务端发送一个字符串(如"Hello Socket"),服务器收到该
字符串后将其打印到命令行上,然后向客户端返回该字符串的长度,最后,客户端输出服务器端返回的该字符串的长度,
分别用TCP和UDP两种方式去实现。
Socket通信流程:
实现代码如下:
TCP:
package scoket; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; /** * 服务端Socket */ public class TCPServer { public static void main(String[] args) throws IOException { // 创建服务端socket,绑定端口号为65000 ServerSocket socket = new ServerSocket(65000); // 构建一个死循环,用来监听并处理客户端请求 while (true) { // 接收一个客户端请求,封装为一个Socket对象 // 此时处于阻塞状态 Socket s = socket.accept(); // 处理收到的请求 // 获取客户端输入流 InputStream in = s.getInputStream(); // 获取客户端输出流 OutputStream out = s.getOutputStream(); // 定义用于存客户端信息的变量 byte[] buff = new byte[1024]; // 从输入流中读取数据 int length = in.read(buff); // 将字节流转化为字符串并在控制台打印 String content = new String(buff, 0, length); System.out.println(content); // 将数据长度转化为字节流并写入输出流 out.write(String.valueOf(length).getBytes()); // 关闭相关流以及socket out.close(); in.close(); s.close(); } } }
package scoket; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; /** * TCP客户端Socket */ public class TCPClient { public static void main(String[] args) throws IOException { // 创建Socket,并指明要连接的服务器IP和端口 Socket socket = new Socket("127.0.0.1", 65000); // 获取socket输入流与输出流 InputStream in = socket.getInputStream(); OutputStream out = socket.getOutputStream(); // 客户端将指定字符串写入流 out.write(new String("Hello Socket").getBytes()); // 客户端接收服务器发送的字符串长度并打印 byte[] buff = new byte[1024]; int length = in.read(buff); String content = new String(buff, 0, length); System.out.println(content); // 关闭相关的流以及Socket in.close(); out.close(); socket.close(); } }
UDP:
package scoket; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; /** * UDP客户端Socket */ public class UDPServer { public static void main(String[] args) throws IOException { // 创建服务端Socket并绑定端口 DatagramSocket socket = new DatagramSocket(65001); // 定义存储客户端信息的变量 byte[] buff = new byte[1024]; // 将信息封装为一个Packet DatagramPacket packet = new DatagramPacket(buff, buff.length); socket.receive(packet); // 从packet中取出真正的数据 byte[] data = packet.getData(); // 处理字节流数据并打印 String content = new String(data, 0, packet.getLength()); System.out.println(content); // 服务端向客户端发送数据报 byte[] length = String.valueOf(packet.getLength()).getBytes(); // 定义新的数据报,并将原客户端的IP和端口封装进数据报中 DatagramPacket lengthPacket = new DatagramPacket(length, length.length, packet.getAddress(), packet.getPort()); // 发送数据给客户端 socket.send(lengthPacket); } }
package scoket; import java.io.IOException; import java.net.*; /** * UDP客户端Socket */ public class UDPClient { public static void main(String[] args) throws IOException { // 创建客户端Socket DatagramSocket socket = new DatagramSocket(); // 封装数据报,并绑定IP和端口 InetAddress address = InetAddress.getByName("127.0.0.1"); // 创建数据信息 byte[] info = "Hello Socket".getBytes(); DatagramPacket packet = new DatagramPacket(info, info.length, address, 65001); // 发送数据给服务端 socket.send(packet); // 接收服务端发来的信息 byte[] buff = new byte[1024]; DatagramPacket lengthPacket = new DatagramPacket(buff, buff.length); socket.receive(lengthPacket); // 取得真正的信息 byte[] data = lengthPacket.getData(); String content = new String(data, 0, data.length); System.out.println(content); } }
值得注意的是,运行代码时,必须先启动Server,再启动Client