我写了一个侦听客户端消息的服务器,它是http://docs.oracle.com/javase/tutorial/networking/sockets/clientServer.html的变种。我在eclipse中将它们作为java类写在同一个项目中。为了测试它,我有一个带有main的客户端类,它启动服务器,然后向它发送消息。当我运行它时,程序只挂起在serverSocket.accept();根据javadoc for ServerSocket接受是不是异步?这可以解释悬挂,但那么教程代码是如何工作的呢?
更新 - 这是我的工作代码: 这是工作代码:
MyServer.java
/*imports neglected for brevity */
public class MyServer {
public static final String hostname = "localhost";
public static final int portNum = 4444;
ServerSocket serverSocket;
BufferedReader serverReader;
File serverLog;
FileWriter fw;
BufferedWriter serverWriter;
Socket clientSocket;
public static void main(String[] args) {
MyServer server = new MyServer(portNum);
// start the server so it can listen to client messages
server.start();
}
public MyServer(int portNum) {
try {
// endpt for server side, used to listen for client socket
serverSocket = new ServerSocket(portNum);
/* have server socket listen for connection, return client socket.
* serverSocket can now talk to clientSocket
*/
clientSocket = serverSocket.accept();
// server writes messages to this log
serverLog = new File("ServerLog.txt");
if(!serverLog.exists())
serverLog.createNewFile();
fw = new FileWriter(serverLog.getAbsoluteFile());
serverWriter = serverWriter = new BufferedWriter(fw);
/* server reads from this stream that is populated by the client's
* OUTPUT stream/client socket's INPUT stream
*/
serverReader = new BufferedReader(
new InputStreamReader(clientSocket.getInputStream())
);
}
catch (Exception e) {
e.printStackTrace();
}
}
public void start() {
String clientMsg;
try {
while((clientMsg = serverReader.readLine()) != null) {
if(clientMsg.startsWith("exit")) {
break;
}
serverWriter.append(clientMsg);
}
serverWriter.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
MyClient.java 公共类MyClient { public static final String hostname =“localhost”; public static final int portNum = 4444;
public static void main(String[] args) {
String msg = "message 1";
try {
// server is listening on http://localhost:4444
Socket serversSocket = new Socket(hostname, portNum);
PrintWriter clientOut = new PrintWriter(serversSocket.getOutputStream(), true);
// send first message
clientOut.println(msg);
msg = "message 2";
// send second message
clientOut.println(msg);
msg = "exit";
// this will stop the server
clientOut.println(msg);
}
catch (Exception e) {
e.printStackTrace();
}
}
}
答案 0 :(得分:1)
如果你完成本教程,它会创建两个应用程序,其中一个是客户端,一个是服务器。
您无法创建这样的变体,因为当您调用构造函数时,您的整个应用程序都会阻止clientSocket = serverSocket.accept();
。
如果您因任何原因坚持创建单个应用程序,则可以执行多线程处理。但我没有看到你为什么要那样做的原因。
答案 1 :(得分:0)
本教程假设您没有在同一程序中运行它们。如果必须在同一程序中运行它们,请在单独的线程中启动服务器。
答案 2 :(得分:0)
如果您有Android手机,可以使用应用TCP套接字进行测试 确保PortForward是服务器正在侦听的端口。 一些isp也阻塞端口,所以请确保所有端口都打开你的isp 相信我在这个上打破了我的头:)
http://docs.oracle.com/javase/6/docs/api/java/net/ServerSocket.html
还要确保您的服务器具有公共IP而不是本地IP
如果你测试这个localy然后上面的代码是好的,如果不是你将需要添加
bind(SocketAddress endpoint)
/*Binds the ServerSocket to a specific address (IP address and port number).*/
你可以通过输入谷歌找到你的IP:我的ip是什么