从客户端接收消息
Receiving messages from Client
我编写了以下连接到客户端的服务器:
ServerSocket server = null;
try
{
server = new ServerSocket(4040);
while (isServerListening)
{
Socket clientSocket = server.accept();
// Send bytes to the Client
ServerOutputStream = clientSocket.getOutputStream();
byte[] bytes = "I am a Server".getBytes();
ServerOutputStream.write(bytes);
}
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
// close socket here
}
此服务器在第 server.accept() 行停止并等待下一个客户端连接。同时我想读取从客户端收到的消息。
几年前我用不同的语言通过事件处理程序进行了套接字编程,但在这里我似乎需要一种不同的方法。
我的问题是:我需要另一个线程来完成这项任务吗?有没有其他选择,例如非阻塞模式?
您可以创建一个线程池并将 clientSocket 作为新任务提交给 ThreadPool
Socket clientSocket = serverSocket.accept();
threadPool.submit(new ClientTask(clientSocket));
您可以在互联网上找到 multi-threaded 服务器的多个实现,查看此 one
My question is: Would I need another thread for this task?
一种方法是为每个客户端连接使用一个线程。应用程序方法在监听端口的无限循环中运行服务器。当请求连接时,它会生成一个新线程来提供服务并立即 returns 进行监听。
ServerSocket listener = new ServerSocket(9898);
try {
while (true) {
new Handler(listener.accept(), clientNumber++).start();
}
} finally {
listener.close();
}
处理特定套接字上的请求的线程。
private static class Handler extends Thread {
private Socket socket;
private int clientNumber;
public Handler(Socket socket, int clientNumber) {
this.socket = socket;
this.clientNumber = clientNumber;
}
public void run() {
try {
BufferedReader in = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
while (true) {
String input = in.readLine();
...
}
} catch (IOException e) {
} finally {
try {
socket.close();
} catch (IOException e) {
log("Couldn't close a socket, what's going on?");
}
}
}
}
Is there an alternative e.g. non-blocking mode?
使用 non-blocking 套接字通道,服务器套接字必须向选择器注册才能执行某些操作。默认情况下,服务器套接字通道是阻塞通道。要使其成为 non-blocking 频道,请设置以下内容。
channel.configureBlocking(false);
Non-blocking 服务器程序看起来像...
InetAddress hostIPAddress = InetAddress.getByName("localhost");
int port = 19000;
Selector selector = Selector.open();
ServerSocketChannel channel = ServerSocketChannel.open();
channel.configureBlocking(false);
channel.socket().bind(new InetSocketAddress(hostIPAddress, port));
channel.register(selector, SelectionKey.OP_ACCEPT);
while (true) {
Set keys = selector.selectedKeys();
...
}
non-blocking 客户端程序看起来像...
InetAddress serverIPAddress = InetAddress.getByName("localhost");
InetSocketAddress serverAddress = new InetSocketAddress(
serverIPAddress, 19000);
Selector selector = Selector.open();
SocketChannel channel = SocketChannel.open();
channel.configureBlocking(false);
channel.connect(serverAddress);
int operations = SelectionKey.OP_CONNECT | SelectionKey.OP_READ
| SelectionKey.OP_WRITE;
channel.register(selector, operations);
while (true) {
if (selector.select() > 0) {
Set keys = selector.selectedKeys();
...
}
}
channel.close();
我编写了以下连接到客户端的服务器:
ServerSocket server = null;
try
{
server = new ServerSocket(4040);
while (isServerListening)
{
Socket clientSocket = server.accept();
// Send bytes to the Client
ServerOutputStream = clientSocket.getOutputStream();
byte[] bytes = "I am a Server".getBytes();
ServerOutputStream.write(bytes);
}
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
// close socket here
}
此服务器在第 server.accept() 行停止并等待下一个客户端连接。同时我想读取从客户端收到的消息。
几年前我用不同的语言通过事件处理程序进行了套接字编程,但在这里我似乎需要一种不同的方法。
我的问题是:我需要另一个线程来完成这项任务吗?有没有其他选择,例如非阻塞模式?
您可以创建一个线程池并将 clientSocket 作为新任务提交给 ThreadPool
Socket clientSocket = serverSocket.accept();
threadPool.submit(new ClientTask(clientSocket));
您可以在互联网上找到 multi-threaded 服务器的多个实现,查看此 one
My question is: Would I need another thread for this task?
一种方法是为每个客户端连接使用一个线程。应用程序方法在监听端口的无限循环中运行服务器。当请求连接时,它会生成一个新线程来提供服务并立即 returns 进行监听。
ServerSocket listener = new ServerSocket(9898);
try {
while (true) {
new Handler(listener.accept(), clientNumber++).start();
}
} finally {
listener.close();
}
处理特定套接字上的请求的线程。
private static class Handler extends Thread {
private Socket socket;
private int clientNumber;
public Handler(Socket socket, int clientNumber) {
this.socket = socket;
this.clientNumber = clientNumber;
}
public void run() {
try {
BufferedReader in = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
while (true) {
String input = in.readLine();
...
}
} catch (IOException e) {
} finally {
try {
socket.close();
} catch (IOException e) {
log("Couldn't close a socket, what's going on?");
}
}
}
}
Is there an alternative e.g. non-blocking mode?
使用 non-blocking 套接字通道,服务器套接字必须向选择器注册才能执行某些操作。默认情况下,服务器套接字通道是阻塞通道。要使其成为 non-blocking 频道,请设置以下内容。
channel.configureBlocking(false);
Non-blocking 服务器程序看起来像...
InetAddress hostIPAddress = InetAddress.getByName("localhost");
int port = 19000;
Selector selector = Selector.open();
ServerSocketChannel channel = ServerSocketChannel.open();
channel.configureBlocking(false);
channel.socket().bind(new InetSocketAddress(hostIPAddress, port));
channel.register(selector, SelectionKey.OP_ACCEPT);
while (true) {
Set keys = selector.selectedKeys();
...
}
non-blocking 客户端程序看起来像...
InetAddress serverIPAddress = InetAddress.getByName("localhost");
InetSocketAddress serverAddress = new InetSocketAddress(
serverIPAddress, 19000);
Selector selector = Selector.open();
SocketChannel channel = SocketChannel.open();
channel.configureBlocking(false);
channel.connect(serverAddress);
int operations = SelectionKey.OP_CONNECT | SelectionKey.OP_READ
| SelectionKey.OP_WRITE;
channel.register(selector, operations);
while (true) {
if (selector.select() > 0) {
Set keys = selector.selectedKeys();
...
}
}
channel.close();