为什么客户端无法再次与服务器连接?何时应该关闭套接字?
第一个客户端发送消息并从服务器接收消息。一切都很好。然后客户端从文件中读取内容并出席发送到服务器。我不知道问题出在哪里。问题是客户端还是服务器?或者我关闭了错误的套接字?
import java.io.*;
import java.net.*;
public class Client {
public static void main(String[] args) throws IOException {
// Connection to Server
String serverHostname = "127.0.0.1";
int port = 10007;
System.out.println("Attemping to connect to host " + serverHostname
+ " on port " + port);
Socket echoSocket = null;
try {
echoSocket = new Socket(serverHostname, port);
} catch (UnknownHostException e) {
System.err.println("Don't know about host: " + serverHostname);
System.exit(1);
} catch (IOException e) {
System.err.println("Couldn't get I/O for the connection to: "
+ serverHostname);
System.exit(1);
}
// Declare the DataOutput and the DataInput
PrintWriter out = new PrintWriter(echoSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(
echoSocket.getInputStream()));
String msgIn, msgOut;
msgOut = "TEST";
out.println(msgOut);
msgIn = in.readLine();
System.out.println("RETURN: " + msgIn);
msgOut = "l";
out.println(msgOut);
msgIn = in.readLine();
System.out.println("RETURN: " + msgIn);
// Close all connections
out.close();
in.close();
echoSocket.close();
}
}
import java.net.*;
import java.io.*;
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(10007);
} catch (IOException e) {
System.err.println("Could not listen on port: 10007.");
System.exit(1);
}
Socket clientSocket = null;
System.out.println("Waiting for connection.....");
try {
// The socket accepted by the client
clientSocket = serverSocket.accept();
System.out.println("Accept connection from "
+ clientSocket.getLocalAddress().toString() + ":"
+ clientSocket.getPort());
} catch (IOException e) {
System.err.println("Accept failed.");
System.exit(1);
}
System.out.println("Connection successful");
System.out.println("Waiting for input.....");
// Get input and output streams associated with the socket.
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(
clientSocket.getInputStream()));
String msgIn, msgOut;
msgIn = in.readLine();
System.out.println("Server IN: " + msgIn);
msgOut = msgIn + " OK ";
out.println(msgOut);
out.close();
in.close();
clientSocket.close();
serverSocket.close();
}
}
Attemping to connect to host 127.0.0.1 on port 10007
RETURN: TEST OK
Exception in thread "main" java.net.SocketException: Software caused connection abort: recv failed
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.socketRead(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at sun.nio.cs.StreamDecoder.readBytes(Unknown Source)
at sun.nio.cs.StreamDecoder.implRead(Unknown Source)
at sun.nio.cs.StreamDecoder.read(Unknown Source)
at java.io.InputStreamReader.read(Unknown Source)
at java.io.BufferedReader.fill(Unknown Source)
at java.io.BufferedReader.readLine(Unknown Source)
at java.io.BufferedReader.readLine(Unknown Source)
at Client.main(Client.java:45)
答案 0 :(得分:0)
当您编写使用TCP进行通信的程序时,它们必须使用某种应用程序级协议进行通信。如果一方要向另一方发送消息,协议必须指定如何标记消息的结尾以及消息将包含哪些字节以及它们的含义。
此类协议的示例包括SMTP(用于发送电子邮件),HTTP(用于发送网页)和FTP(用于发送文件)。其中每个都有一个书面文档,解释了交换的字节数,它们的含义,以及发送者和接收者如何编码和解析它们。
如果没有这样的规范,就无法弄清楚你的服务器和客户端是否做了他们应该做的事情,因为"他们应该做什么"还没有形成。
查看现有协议规范,并为服务器和客户端使用的协议编写一个规范。然后,您可以检查服务器和客户端是否符合协议以进行调试。
第一次这样做会很困难,但经过几次会变得更容易。编写可靠的网络软件至关重要。只有运气没有指定的协议,你才能成功。
TCP是字节流协议,而不是消息协议。您的应用程序正在尝试发送和接收消息,因此您需要一个应用程序级消息协议来定义它们如何执行此操作。然后,您需要编写代码来发送和接收应用程序级协议定义的消息"。没有它,你正在尝试不可能的事情 - 尝试发送没有任何代码的消息,这些代码知道什么是"消息"实际上是。
例如,您的协议可以定义"消息" as"一组不包含任何换行符的字节或由换行符终止的零字节"。然后你可以编写代码来发送"消息"通过在最后添加换行符和代码来接收"消息"通过检索字节块并扫描它们换行。但你还没有那样做。