简单socket通信,回显 服务器程序与客户端程序之间的通信。
Socket 通信编程是一种基于网络的通信方式,允许不同主机上的程序通过网络进行数据交换。
实现结构try catch:
前情了解:
1.如何创建服务器端
定义ServerSocket套接字,需要等待客户端连接,阻塞,直到接入连接,然后,建立与客户端的输入输出流,用while读取并发送字符串,定义结束字符“end”.最后关闭该socket.
步骤 1:创建 ServerSocket
· 使用 ServerSocket 类创建一个服务器端套接字,并绑定到一个指定的端口上。
· 该端口用于监听客户端的连接请求。
int port = 9000; // 定义服务器监听的端口号 ServerSocket serverSocket = new ServerSocket(port); System.out.println("服务器已启动,监听端口:" + port);
步骤 2:等待客户端连接
· 调用 serverSocket.accept() 方法等待客户端的连接请求。
· 该方法是阻塞式的,直到有客户端连接才会返回一个 Socket 对象,表示与客户端的连接。
Socket clientSocket = serverSocket.accept(); System.out.println("客户端已连接,IP 地址:" + clientSocket.getInetAddress());
步骤 3:建立 I/O 流
· 通过 Socket 对象获取输入流和输出流,用于与客户端进行数据传输。
· 输入流用于从客户端读取数据,输出流用于向客户端发送数据。
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
步骤 4:处理客户端请求
· 使用输入流读取客户端发送的数据。
· 根据需要处理数据,并通过输出流向客户端发送响应。
String clientMessage; while ((clientMessage = in.readLine()) != null) {System.out.println("收到客户端消息:" + clientMessage);out.println("服务器已收到:" + clientMessage);if ("bye".equalsIgnoreCase(clientMessage.trim())) {break; // 如果客户端发送 "bye",结束通信} }
步骤 5:关闭连接
通信结束后,关闭输入流、输出流和 Socket 对象,释放资源。
in.close(); out.close(); clientSocket.close(); serverSocket.close();
2.如何创建客户端
步骤 1:创建 Socket
使用 Socket 类创建一个客户端套接字,并连接到服务器的 IP 地址和端口。
如果连接成功,Socket 对象将表示与服务器的连接。
String serverAddress = "localhost"; // 服务器的 IP 地址 int port = 9000; // 服务器监听的端口号 Socket socket = new Socket(serverAddress, port); System.out.println("已连接到服务器");
步骤 2:建立 I/O 流
通过 Socket 对象获取输入流和输出流,用于与服务器进行数据传输。
输入流用于从服务器读取数据,输出流用于向服务器发送数据。
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); PrintWriter out = new PrintWriter(socket.getOutputStream(), true); BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
步骤 3:发送请求并接收响应
使用输出流向服务器发送数据。
使用输入流接收服务器的响应。
String userInput; while ((userInput = stdIn.readLine()) != null) {out.println(userInput); // 向服务器发送数据System.out.println("服务器响应:" + in.readLine()); // 接收服务器的响应if ("bye".equalsIgnoreCase(userInput.trim())) {break; // 如果发送 "bye",结束通信} }
步骤 4:关闭连接
通信结束后,关闭输入流、输出流和 Socket 对象,释放资源。
in.close(); out.close(); stdIn.close(); socket.close();
代码参考:
Server端:
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.BindException; import java.net.ServerSocket; import java.net.Socket; public class Server {public static void main(String[] args) throws IOException {try {//服务器程序在本机9000端口监听ServerSocket server=new ServerSocket(9000);Socket socket=server.accept();//等待客户端连接,阻塞,直到接入连接//建立与客户端输入/输出流BufferedReader in =new BufferedReader(new InputStreamReader(socket.getInputStream()));PrintWriter out=new PrintWriter(socket.getOutputStream());while(true) {String str=in.readLine();//从客户端读取一行字符串System.out.println("接收到:"+str);out.println("已接受到:"+str);//向客户端发送字符串out.flush();//刷空输出流if(str.equals("end")) break;}socket.close();}catch(BindException e) {e.printStackTrace();}}}
Client端:
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 {public static void main(String[] args) {try {//创建socket连接本机//服务器程序也在本机运行,在9000端口监听Socket socket=new Socket(InetAddress.getLocalHost(),9000);//下面建立和服务器的输入/输出流BufferedReader in=new BufferedReader(new InputStreamReader(socket.getInputStream()));PrintWriter out = new PrintWriter(socket.getOutputStream());//创建键盘的输入流BufferedReader wt=new BufferedReader(new InputStreamReader(System.in));while(true) {String str=wt.readLine();out.println(str);out.flush();if(str.equals("end")) {break;}System.out.println("对方发来:"+in.readLine());}socket.close();}catch(IOException e){e.printStackTrace();}}}
运行输出:
先运行server程序,再运行client程序,再cient程序的控制台console中可以输入你想输入的东西,可以看到server端的响应,可以切换着查看两程序console内容。
server端的console控制台:
client端的console控制台:
端口占用问题:
如果端口占用,可以到c盘中的该路径(C:\Windows\System32>)下cmd直接进入,
C:\Windows\System32>netstat -ano | findstr 9000
netstat -ano | findstr 9000
//使用上述命令查看端口是否被占用,若被占用可能会显示:
TCP 0.0.0.0:9000 0.0.0.0:0 LISTENING 9388 TCP [::]:9000 [::]:0 LISTENING 9388
//上述显示表明,进程 9388 正在监听端口 9000
taskkill /PID 9388 /F
//可以使用上述命令杀死进程9388,不过需要先看一下9388是否重要,不确定进程 9388 是否可以安全结束,要先通过任务管理器查看该进程的详细信息,避免误杀重要进程。
/PID
参数指定进程 ID。
/F
参数强制结束进程所以,最好使用没有占用的端口。