Java Socket点对点通信(基于 TCP)

2014-06-22· 6942 次浏览
## ![TIM截图20180508131305.jpg](https://image.xsoftlab.net/baike/articleImages/a082167987078b93b7c549104b8ef46d.jpg) ## 介绍 Socket通常称作“套接字”,用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过Socket向网络发出请求或者应答网络请求。 Socket是在建立网络连接时使用,在连接成功时,应用程序两端都会产生一个Socket实例,操作这个实例,完成所需的会话。· 对于一个网络连接来说,socket是平等的,并没有差别,不因为在服务器端或在客户端而产生不同级别。 Socket服务器端需要在某个端口上开启服务器端类型的类:java.net.ServerSocket,通过accept()方法用于产生“阻塞”,直到接收到一个连接,并且返回一个客户端的Socket对象实例。 “阻塞”是使程序运行暂时“停留”在这个地方,直到一个会话产生,然后程序继续,通常“阻塞”是由循环产生的。 Socket客户端根据服务器端的IP地址和端口号创建一个Socket对象,连接服务器。 服务器端和客户端都持有一个Socket对象,服务器端的Socket从服务器端指向客户端,而客户端的Socket从客户端指向服务器端,就像在服务器端和客户端建立了两条单向的管道。 ### Socket服务器端 ```java import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; public class SocketServer { private int port; public SocketServer(int port) { this.port = port; try { start(); } catch (Exception e) { System.out.println("启动服务器端出现错误:" + e.getMessage()); } } // 处理信息 public String infoUpperCase(String line) { return line.toUpperCase(); } // 启动服务器端 @SuppressWarnings("resource") public void start() throws IOException { // 根据端口创建服务器端Socket对象 ServerSocket serverSocket = new ServerSocket(port); // 显示连接信息 System.out.println("服务器已启动,监听端口号为:" + port); System.out.println("正在等待客户端连接........."); // 挂起等待客户的请求 Socket socketAccept = serverSocket.accept(); // 获取读取客户端的数据流 BufferedReader in = new BufferedReader(new InputStreamReader(socketAccept.getInputStream())); // 获取写往客户端的数据输出流,true:自动刷新 PrintWriter out = new PrintWriter(socketAccept.getOutputStream(), true); out.println("服务器端连接成功.........");// 向客户发送连接信息 out.println("输入exit断开与服务器的连接"); boolean done = false; while (!done) { // 读取客户端每行的内容 String line = in.readLine(); // 没有写则不读取 if (line == null) { done = true; } else { System.out.println("客户端传来的内容:" + line); // 信息处理 String message = infoUpperCase(line); // 向客户端发送信息 out.println("从服务器端口发送的内容:" + message); // 退出判断 if (line.trim().equals("exit")) done = true; } } socketAccept.close(); } public static void main(String[] args) { try { new SocketServer(9000); } catch (Exception e) { System.out.println("测试服务器端监听出错:" + e.getMessage()); } } } ``` ### Socket客户端 ```java import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.InetAddress; import java.net.Socket; public class Client { private String host; private int port; public Client(String host, int port) { this.host = host; this.port = port; try { connectSocket(); } catch (IOException e) { System.out.println("连接服务器出现I/O错误!"); } } public void connectSocket() throws IOException { Socket socketConn; // 判断IP地址(域名)如果是本机localhost if (host.equals("localhost") || host.equals("127.0.0.1")) { // 创建本地连接 socketConn = new Socket(InetAddress.getLocalHost(), port); } else { // 创建远程连接 socketConn = new Socket(InetAddress.getByName(host), port); } // 获得键盘的输入流 BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in)); // 获得服务器的输出流 PrintWriter out = new PrintWriter(socketConn.getOutputStream(), true); // 获得接收服务器发送内容的缓冲流 BufferedReader in = new BufferedReader(new InputStreamReader(socketConn.getInputStream())); System.out.println("服务器信息:" + in.readLine());// 从服务器获得信息 System.out.println("服务器信息:" + in.readLine()); System.out.print("请输入>");// 用户输入 boolean done = false; while (!done) { // 获得从键盘输入的每行字符 String line = stdin.readLine(); // 发送到服务端 out.println(line); // 读到exit则结束循环 if (line.equalsIgnoreCase("exit")) done = true; // 从服务器读取字符串 String info = in.readLine(); // 显示从服务器发送来的数据 System.out.println("服务器信息:" + info); if (!done) System.out.print("请输入>"); } // 关闭资源 socketConn.close(); } public static void main(String[] args) { try { // IP地址为本机,端口为9000 new Client("localhost", 9000); } catch (Exception e) { System.out.println("测试客户端连接出错:" + e.getMessage()); } } } ```