
Java网络编程——Socket套接字入门
什么是Socket
Socket 是一种网络协议,可以让服务器和客户端保持互联,常用于通讯软件的协议。
Socket实例
建立连接的语法非常简单,如下:
Socket socket = new Socket(host, port);
当然,Socket也可以获取流,并且支持 try_catch_resource
try (Socket socket = new Socket("bbs.newsmth.net", 23)) {
InputStream is = socket.getInputStream();
Scanner scanner = new Scanner(is, "gbk");
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
System.out.println(line);
}
} catch (UnknownHostException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
ServerSocket实例
ServerSocket
就是 Socket
的服务端(数据响应),代码示例如下:
try(ServerSocket server = new ServerSocket(8881);
Socket socket = server.accept();
InputStream is = socket.getInputStream();
OutputStream os = socket.getOutputStream();
Scanner scanner = new Scanner(is)){
PrintWriter pw = new PrintWriter(new OutputStreamWriter(os, "gbk"), true);
pw.println("SOCKET 200 OK,输入【exit】退出");
boolean done = false;
while(!done && scanner.hasNextLine()) {
String line = scanner.nextLine();
System.out.println(line);
if ("exit".equals(line)) done = true;
}
} catch (IOException e) {
throw new RuntimeException(e);
}
其中的
Socket socket = server.accept()
accept
方法:ServerSocket 的accept
方法是一个阻塞式方法 。这意味着当执行到这行代码时,服务器端程序会暂停在此处,持续监听指定端口,直到有客户端尝试连接到这个端口。一旦检测到有客户端连接请求,它就会接受这个连接请求,并返回一个和客户端通信的 Socket 对象。
启动 ServerSocket
后,可以使用 telnet
测试
telnet 127.0.0.1 8881
结果如下:
多个客户端
Socket默认其实只支持一对一服务,如果想要接受多个Socket请求的话,可以启用一个进程来处理。
模板:
try (ServerSocket server = new ServerSocket(8881)) {
while (true) {
Socket socket = server.accept();
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
// 套接字处理程序
}
});
thread.start();
}
} catch (IOException e) {
e.printStackTrace();
}
使用示例:
try (ServerSocket server = new ServerSocket(8881)) {
while (true) {
Socket socket = server.accept();
Thread thread = new Thread(() -> {
try (InputStream is = socket.getInputStream();
OutputStream os = socket.getOutputStream();
Scanner scanner = new Scanner(is)
) {
PrintWriter pw = new PrintWriter(new OutputStreamWriter(os, "gbk"), true);
pw.println("SOCKET 200 OK,输入【exit】退出");
boolean done = false;
while (!done && scanner.hasNextLine()) {
String line = scanner.nextLine();
System.out.println("接受到来自端口: "+socket.getPort() + " 的信息\t" +line);
if ("exit".equals(line)) done = true;
}
} catch (IOException e) {
throw new RuntimeException(e);
}
});
thread.start();
}
} catch (IOException e) {
e.printStackTrace();
}
测试:
多线程开发
关于线程:多线程
刚刚上面的一对多关系其实就是使用多线程,以下示例将会自定义ClientHandler 辅助开发,同时也会搭建客户端
Server
:
public class MultiThreadedServer {
public static void main(String[] args) throws IOException {
int port = 12345;
ServerSocket server = new ServerSocket(port);
System.out.println("Server is listening on port: " + port);
while (true) {
Socket socket = server.accept();
System.out.println("Client connected.");
new ClientHandler(socket).start();
}
}
}
class ClientHandler extends Thread {
private final Socket socket;
public ClientHandler(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try (
InputStream is = socket.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
OutputStream os = socket.getOutputStream();
PrintWriter writer = new PrintWriter(os, true)
) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println("Reviced: " + line);
writer.println("Server: " + line);
}
socket.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
client
:
public class Client {
public static void main(String[] args) throws IOException {
String hostname = "localhost";
int port = 12345;
Socket socket = new Socket(hostname, port);
System.out.println("Connected to server: " + socket);
InputStream is = socket.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
OutputStream os = socket.getOutputStream();
PrintWriter writer = new PrintWriter(os, true);
writer.println("Hello, server!");
String response = reader.readLine();
System.out.println("Server response: " + response);
socket.close();
}
}
DatagramSocket实例
DatagramSocket
是 Java 中实现 UDP协议的核心类,可以使用 UDP 协议为Socket通信。
服务器端代码:
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class UDPServer {
public static void main(String[] args) throws IOException {
int port = 12345;
DatagramSocket serverSocket = new DatagramSocket(port);
System.out.println("Server is listening on port " + port);
byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
serverSocket.receive(packet);
String message = new String(packet.getData(), 0, packet.getLength());
System.out.println("Received: " + message);
serverSocket.close();
}
}
客户端代码:
import java.io.IOException;
import java.net.*;
public class UDPClient {
public static void main(String[] args) throws IOException {
String hostname = "localhost";
int port = 12345;
InetAddress address = InetAddress.getByName(hostname);
DatagramSocket clientSocket = new DatagramSocket();
String message = "Hello, server!";
byte[] buffer = message.getBytes();
DatagramPacket packet = new DatagramPacket(buffer, buffer.length, address, port);
clientSocket.send(packet);
System.out.println("Message sent");
clientSocket.close();
}
}
在这个示例中,服务器端创建一个 DatagramSocket 对象并监听端口 12345。然后,它创建一个 DatagramPacket 对象,用于存储接收到的数据包。serverSocket.receive(packet)
方法阻塞,直到收到一个数据包。收到数据包后,服务器从数据包中提取并打印消息。
客户端首先解析服务器的 IP 地址,然后创建一个 DatagramSocket 对象。接着,客户端创建一个包含要发送消息的 DatagramPacket 对象,并指定目标地址和端口。最后,客户端通过调用 clientSocket.send(packet)
方法发送数据包。
- 感谢你赐予我前进的力量
赞赏者名单
因为你们的支持让我意识到写文章的价值🙏
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 zxb
评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果