我有一些简单的客户端和服务器代码,其中客户端向服务器发送一些字节,服务器以一些字节进行响应。客户端打印收到的字节,然后关闭套接字。
这在客户端第一次运行时效果很好,但是随后的调用没有响应。
package sockets.com;
// Client Side
import java.io.*;
import java.net.*;
public class ClientSideTCPSocket {
public void run() {
try {
int serverPort = 4023;
InetAddress host = InetAddress.getByName("localhost");
System.out.println("Connecting to server on port " + serverPort);
Socket socket = new Socket(host, serverPort);
System.out.println("Just connected to " + socket.getRemoteSocketAddress());
OutputStream out = socket.getOutputStream();
InputStream in = socket.getInputStream();
String s = "HELLO SERVER";
byte[] bytes = s.getBytes("US-ASCII");
for (byte b : bytes) {
out.write(b);
}
int ch = 0;
while ((ch = in.read()) >= 0) {
System.out.println("Got byte " + ch);
}
out.flush();
out.close();
socket.close();
} catch (UnknownHostException ex) {
ex.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
ClientSideTCPSocket client = new ClientSideTCPSocket();
client.run();
}
}
服务器代码
package sockets.com;
//Server Side
import java.net.*;
import java.io.*;
public class ServerSideTCPSocket {
public void run() {
try {
int serverPort = 4023;
ServerSocket serverSocket = new ServerSocket(serverPort);
serverSocket.setSoTimeout(900000);
while (true) {
System.out.println("Waiting for client on port " + serverSocket.getLocalPort() + "...");
Socket server = serverSocket.accept();
System.out.println("Just connected to " + server.getRemoteSocketAddress());
//
int ch = 0;
while ((ch = server.getInputStream().read()) >= 0) {
System.out.println("Got byte " + ch);
}
// Write to output stream
OutputStream out = server.getOutputStream();
String s = "HELLO CLIENT";
byte[] bytes = s.getBytes("US-ASCII");
for (byte b : bytes) {
System.out.println(b);
out.write(b);
}
}
} catch (UnknownHostException ex) {
ex.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
ServerSideTCPSocket srv = new ServerSideTCPSocket();
srv.run();
}
}
对于有关为何如此的任何评论将不胜感激。谢谢。
答案 0 :(得分:0)
几件事:
此代码块将永远循环,直到客户端关闭其连接为止:
while ((ch = server.getInputStream().read()) >= 0) {
System.out.println("Got byte " + ch);
}
然后,在客户端关闭其连接之后,随后尝试将“ HELLO CLIENT”发送到套接字将生成IO异常。这将触发服务器循环退出。
最简单的解决方法是调整协议,以便在某些定点字符上完成“消息”。在我的简单修复中,我只是对其进行了调整,使其在收到!
时爆发。
最好让每个客户端会话都在ioexception而不是整个服务器块上终止。我对您的代码的重构:
public class ServerSideTCPSocket {
public void tryCloseSocketConnection(Socket socket) {
try {
socket.close();
}
catch(java.io.IOException ex) {
}
}
public void processClientConnection (Socket clientConnection) throws java.io.IOException {
int ch = 0;
while ((ch = clientConnection.getInputStream().read()) >= 0) {
System.out.println("Got byte " + ch);
if (ch == '!') {
break;
}
}
// Write to output stream
OutputStream out = clientConnection.getOutputStream();
String s = "HELLO CLIENT!";
byte[] bytes = s.getBytes("US-ASCII");
for (byte b : bytes) {
System.out.println(b);
out.write(b);
}
}
public void run() {
try {
int serverPort = 4023;
ServerSocket serverSocket = new ServerSocket(serverPort);
serverSocket.setSoTimeout(900000);
while (true) {
System.out.println("Waiting for client on port " + serverSocket.getLocalPort() + "...");
Socket clientConnection = serverSocket.accept();
try {
System.out.println("Just connected to " + clientConnection.getRemoteSocketAddress());
processClientConnection(clientConnection);
}
catch (java.io.IOException ex) {
System.out.println("Socket connection error - terminating connection");
}
finally {
tryCloseSocketConnection(clientConnection);
}
}
}
catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
ServerSideTCPSocket srv = new ServerSideTCPSocket();
srv.run();
}
}
然后将客户代码的消息调整为:
String s = "HELLO SERVER!"; // the exclamation point indicates "end of message".