Java 套接字:创建客户端/服务器聊天应用程序
在本教程中,您将学习如何使用套接字在两台计算机之间创建 java 聊天应用程序。例如,在开始编程部分之前,您需要配置网络以使这两台机器在您家的本地网络上进行交互。我们将实现我们在理论上看到的内容:众所周知的客户端/服务器模型。在本教程结束时,您将了解套接字如何交换消息。
Server
javaserver> 初始化连接,侦听端口,并等待传入连接接受。例如,端口号为 5000,客户端向具有此端口号 5000 的服务器发送请求。服务器接受请求并将其信息(IP 地址)传输到客户端。现在连接已建立,可以进行消息交换。Java 提供了一个包 java.net 来处理所有网络,你只需要两个类:
- java.net.ServerSocket:此类接受来自客户端的连接。
- java.net.Socket:此类连接到远程计算机。
- 扫描:读取键盘输入.
- BufferedReader:读取从发送方接收的文本。
- PrintWriter:发送键入的文本.
ServerSocket socket socketserver;创建端口号为 5000 的服务器套接字后,服务器将等待传入连接,一旦检测到一个连接,它就会接受它。处理读写流的两个变量 in 和 out 被初始化为直接链接到发送和接收流。
Socket socket的服务器;
final BufferedReader in;
final PrintWriter 输出;
final 扫描仪 sc=new 扫描仪(System.in);
try {
socketserver = new ServerSocket(5000);
serversocket = socketserver.accept();
out = new PrintWriter(serversocket.getOutputStream());
in = new BufferedReader (new InputStreamReader (serversocket.getInputStream()));
字符串 s;
s = sc.next();
out.println(s);
out.flush();
字符串message_client;
message_client = in.readLine();
System.out.println(客户端:”+message_client);
}
catch (IOException e) {
e.printStackTrace();
}
变量 s 存储使用 next(),然后用 println(s).
flush() 很重要,因为它会将写入缓冲区刷新到输出,否则 null 将由另一台计算机接收。
变量 message_client 存储消息 显示为 println().
此代码的局限性在于它只能发送和接收一次消息。你会有一个想法:添加一个循环 while(true)。这是正确的,但是,例如,如果服务器向客户端发送消息,则客户端无法检索该消息,直到它也发送该消息。最佳解决方案是创建两个线程:一个用于发送,另一个用于接收。这两个过程都允许同时发送和接收。
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
/*
* www.codeurjava.com
*/
public class Server {
public static void main(String[] test) {
final ServerSocket serverSocket;
final Socket clientSocket;
最终的 BufferedReader in;
最终 PrintWriter 输出;
扫描仪 sc=new 扫描仪(System.in);
try {
serverSocket = new ServerSocket(5000);
clientSocket = serverSocket.accept();
out = new PrintWriter(clientSocket.getOutputStream());
in = new BufferedReader (new InputStreamReader (clientSocket.getInputStream())));
线程发送= new Thread(new Runnable() {
字符串消息;
@Override
public void run() {
while(true){
msg = sc.nextLine();
out.println(msg);
out.flush();
}
}
});
发送.start();
线程 receive= new Thread(new Runnable() {
String msg;
@Override
public void run() {
try {
msg = in.readLine();
//只要客户端连接就行
while(msg!=null){
System.out.println(Client: ”+msg);
msg = in.readLine();
}
//如果客户端已解析,则退出循环
System.out.println(客户端解析”);
//关闭流和会话 socket
out.close();
clientSocket.close();
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
});
receive.start();
}catch (IOException e) {
e.printStackTrace();
}
}
}
两个进程的分离是明确的,服务器和客户端可以随时无限地交换数据。播放的 while 循环测试连接是否仍处于建立状态。请记住在退出循环后关闭读写流以及连接,close()。
Client
Client 只需要 Socket 建立 server 连接,开启构造函数将服务器的 IP 地址和端口号作为输入。其余代码与 server.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
/*
* www.codeurjava.com
*/
public class Client {
public static void main(String[] args) {
final Socket clientSocket;
最终的 BufferedReader in;
最终 PrintWriter 输出;
final Scanner sc = new Scanner(System.in);//从keyboard读取
try {
/*
* 服务器信息(端口和 IP 地址或主机名
* 127.0.0.1 是机器的本地地址
*/
clientSocket = new Socket(127.0.0.1”,5000);
//要发送的流
out = new PrintWriter(clientSocket.getOutputStream());
//要接收的流
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
线程发送 = new Thread(new Runnable() {
字符串消息;
@Override
public void run() {
while(true){
msg = sc.nextLine();
out.println(msg);
out.flush();
}
}
});
发送.start();
接收线程 = new Thread(new Runnable() {
字符串消息;
@Override
public void run() {
try {
msg = in.readLine();
while(msg!=null){
System.out.println(服务器:”+msg);
msg = in.readLine();
}
System.out.println(解析服务器”);
out.close();
clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
});
receive.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Execution:
注:如果在同一台机器上工作,则必须运行两次 Eclipse,一次用于服务器,另一次用于客户机。观看以下 YouTube 视频:
https://www.youtube.com/watch?v=d-eD6EDa3io
参考:
Java 中的网络 - 操作 IP 地址
如何检索服务器/客户端的名称和本地 IP 地址
Openclassrooms:套接字简介
Java doc:类 Socket
![]() |
服务器 window |
![]() |
客户机 window |
https://www.youtube.com/watch?v=d-eD6EDa3io
参考:
Java 中的网络 - 操作 IP 地址
如何检索服务器/客户端的名称和本地 IP 地址
Java doc:类 Socket