我创建了2个带套接字的Java程序。我希望客户端向服务器发送连续的数据。但是在消息发送到服务器后,客户端继续向服务器发送“空值”(当我关闭客户端程序中的套接字时发生)。这是我的代码:
import ...
public class MainClient {
private Socket serverSock;
private PrintStream clientOutput;
public static void main(String[] args) {
MainClient client = new MainClient();
client.runClient();
}
public void runClient() {
try {
serverSock = new Socket("127.0.0.1",8282);
clientOutput = new PrintStream(serverSock.getOutputStream());
clientOutput.println("Hello, I'm Connected.");
for (int i=0;i<5;i++) {
clientOutput.println(i + "");
clientOutput.flush();
}
} catch (IOException e) {
e.printStackTrace();
}finally {
// try {
// serverSock.close(); It will keeps sending 'null' data to the server if I use this line.
// } catch (IOException e) {
// e.printStackTrace();
// }
}
}
}
服务器端:
public class MainServer {
private ServerSocket serverSocket;
private int listenPort = 8282;
private InputStream inps;
private Socket clientSocket;
private BufferedReader clientInput;
private MainServer() {
String clientMsg = "";
try {
serverSocket = new ServerSocket(listenPort);
System.out.println("Server is Listening on " + listenPort);
clientSocket = serverSocket.accept();
clientInput = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
while(clientSocket.isConnected()) {
clientMsg = clientInput.readLine();
System.out.println("Client : " + clientMsg);
}
}catch(IOException ex) {
ex.printStackTrace();
}finally {
try {
clientSocket.close();
} catch (IOException e) {}
}
}
public static void main(String[] args) {
new MainServer();
}
}
我试图用clientOutput关闭客户端的OutputStream。close()
但它在发送0-4循环后向服务器发送空值。为了让它停止并避免客户端发送空数据,我不应该插入
serverSock。close()
,但它将返回SocketException。我希望客户在完成后发送“关闭”消息。
总之,服务器上的输出是:
Client: 0
Client: 1
Client: 2
Client: 3
Client: 4
Client: null
Client: null
//And so on..
我想客户程序中缺少了一些东西,我想?谢谢你的帮助:)
通常代码应该是类似的
private MainServer() {
String clientMsg = "";
try {
serverSocket = new ServerSocket(listenPort);
System.out.println("Server is Listening on " + listenPort);
clientSocket = serverSocket.accept();
clientInput = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
while ((clientMsg = clientInput.readLine()) != null) {
if(isTerminationString(clientMsg)) {
break;
}
System.out.println("Client : " + clientMsg);
}
} catch (IOException ex) {
ex.printStackTrace();
} finally {
try {
clientSocket.close();
} catch (IOException e) {
}
}
}
boolean isTerminationString(String msg) {
return msg.equals("DONE!");
}
在isTerminationString
中检查消息是否为终止消息时,客户端和服务器之间应共享通信协议。我举了一个发送已完成消息的例子,但它可能比这更复杂。由于关闭套接字上的close
方法并不能保证另一部分的套接字也会关闭,因此使用isClosed
方法可能无效,并会导致与您相同的问题。
您的MainClient()没有问题。
clientSocket。MainServer()中的isConnected()函数始终检查客户端的状态,这会导致无限循环,因此在消息“client:4”后,clientInput。readLine()应返回“null”。
因此,不必检查客户端套接字是否已连接,您可以检查客户端套接字是否已关闭或未使用函数“clientSocket”。isClosed()。
用下面的代码替换MainServer()中的同时循环,
while(!clientSocket.isClosed()) {
clientMsg = clientInput.readLine();
System.out.println("Client : " + clientMsg);
if(clientMsg.equals("Closed")){
clientSocket.close();
// serverSocket.close();
}
}
这将帮助您在从服务器接收“Closed”消息时关闭客户端套接字,从而避免无限执行while循环以及空语句打印。代码“serverSocket.close()”帮助您关闭服务器套接字,如果需要停止端口侦听,可以在“MainServer()”中使用该代码。
正如评论所指出的,客户端没有发送null
值。
isConnected()
isConnected()
在套接字转换为已连接状态后立即变为true,并在此后保持true,即使在套接字关闭后也是如此。请参阅此讨论和stackoverflow上的其他讨论。
确定对等方是否已经关闭连接的正确方法是尝试从套接字中读取,然后检查结果以寻找关闭的证据。请阅读您正在使用的方法的Javadocs,它们会告诉您各种返回值的含义。对于
BufferedReader.readLine()
方法,它说:
返回:
一个包含行内容的字符串,不包括任何行终止字符,如果已到达流的结尾,则返回null;
抛出:
IOException-如果发生I/O错误
因此,您需要检查null返回值以检测正常的套接字关闭,以及是否收到指示某种网络异常的IOException。
我有一个关于Java插座的技术问题。 例如,假设我有一个Java Sockets服务器和n个多个客户端。是否可以几乎实时地将数据从服务器发送到任何或所有客户端? 更准确地说: 有哪种监听器可以在Sockets客户端中实现 有人能告诉我什么方法是最好的吗?此外,如果有人有一个代码示例,我也会很高兴。 谢谢
我也试图从Java服务器和Python客户机传输数据。我成功地将数据从客户端传输到服务器,但根本没有接收到数据。 在python客户机上,我有以下内容:(注意,这是在一个单独的线程中运行的) 如果这是成功的工作,输出将是客户端套接字值,等待服务器,然后得到一些数据。然而,它正陷入等待数据的困境。 这意味着套接字显然不是None,它正在等待缓冲区接收?我将接收缓冲区大小设置为1,以查看是否有任何数据
我正在做一个正在改造/现代化的项目,其中有一个小的RMI部分,不幸的是,我以前从未与RMI合作过。 我不明白的一件事是,为什么在我最初创建RMI客户端之后,它一直调用其自定义SocketFactory构造函数。似乎每5分钟我就会看到一次调用构造函数的输出,即使客户端和服务器之间没有通信。 连接完成后,我应该做什么来清理和停止任何线程以进行持久化? 我在检查UnicastRemoteObject,也
我正试图从套接字服务器(Java)向套接字客户端(Python)发送一个映像,但客户端中接收到的映像大小不正确,无法打开。我不知道我做错了什么。有什么建议吗?
我希望能够连接到需要智能卡的个人证书进行身份验证的https站点。我想我已经很接近让它工作了,但不知道如何克服这个例外: 由于合同关系,我不能共享我的代码,但这里有一个总结: 我创建了一个密钥库,其中包含从浏览器导出的所有证书。我使用此密钥存储作为SSLContext的信任存储。我非常肯定这个密钥库包含正确的CA证书来验证远程站点的证书,因为它修复了“无法找到请求目标的有效证书路径”的异常。 我可