[英]Server: Socket hangs within unpredictable period time at read stream function
我寫了一個Java套接字服務器,它將保持連接狀態,直到客戶端斷開連接為止。 而且我的客戶端代碼將繼續向該服務器應用推送消息。
但是,當我一段時間運行這些程序時,我似乎也出現了一個不尋常的情況,即服務器會在不可預測的時間內從客戶端讀取輸入流時掛起。 它總是掛在inData.read(b)
因為發生此問題時我看到它在日志上打印出“正在接收...”;即使我殺死了我的客戶端,服務器應用程序仍然掛在那里。
但是,在發生此問題之后,當我在運行服務器應用程序的控制台上按Ctrl+C
時,它將繼續工作。 真煩人。
無論如何,有沒有很好地解決這個不尋常的問題?
服務器代碼:
static ServerSocket server;
try {
server = new ServerSocket("1234");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Socket socket = null;
String inIp = null;
BufferedInputStream inData;
BufferedOutputStream outData;
while (true) {
try {
synchronized (server) {
socket = server.accept();
}
inIp = String.valueOf(socket.getInetAddress());
if (Log4j.log.isEnabledFor(Level.INFO)) {
Log4j.log.info("Incoming connection " + inIp);
}
while (true) {
inData = new BufferedInputStream(socket.getInputStream());
outData = new BufferedOutputStream(socket.getOutputStream());
String reply = "Hey";
byte[] b = new byte[10240];
String data = "";
int length;
if (Log4j.log.isEnabledFor(Level.INFO)) {
Log4j.log.info("InetAddr = " + inIp + ", receiving...");
}
// read input stream
length = inData.read(b);
data += new String(b, 0, length);
if (Log4j.log.isEnabledFor(Level.INFO)) {
Log4j.log.info("Data Length: " + length + ", Received data: " + data);
}
// output result
outData.write(reply.getBytes());
outData.flush();
}
} catch (Exception e) {
String tempStr = e.toString();
Log4j.log.error("Service error during executing: " + tempStr);
}
}
客戶代碼:
Socket client = new Socket();
InetSocketAddress isa = new InetSocketAddress("127.0.0.1", "1234");
String data = "Hi";
while(true) {
try {
if(!client.isConnected())
client.connect(isa, 30000);
BufferedOutputStream out = new BufferedOutputStream(client.getOutputStream());
BufferedInputStream in = new BufferedInputStream(client.getInputStream());
// send msg
out.write(data.getBytes());
out.flush();
System.out.println("Message sent, receiving return message...");
// get return msg
int length;
byte[] b = new byte[10240];
// read input stream
length = in.read(b);
retMsg = new String(b, 0, length);
System.out.println("Return Msg: " + retMsg);
Thread.sleep(60000);
} catch (java.io.IOException | InterruptedException e) {
System.out.println("Socket Error!");
System.out.println("IOException :" + e.toString());
}
}
try {
server = new ServerSocket("1234");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
不要寫這樣的代碼。 catch
塊應位於末尾,所有依賴於new ServerSocket
成功的代碼都應位於try
塊內。
synchronized (server) {
socket = server.accept();
}
此處不需要同步。
while (true) {
inData = new BufferedInputStream(socket.getInputStream());
outData = new BufferedOutputStream(socket.getOutputStream());
問題的大部分(如果不是全部)都在這里。 您每次圍繞此循環都將繼續創建新的緩沖流,這意味着先前流已緩沖的所有內容都將被丟棄。 因此,您正在失去輸入。 您應該在循環之前創建這兩個流。
while(true) {
try {
if(!client.isConnected())
client.connect(isa, 30000);
這是沒有意義的。 去掉。 您尚未顯示client
套接字的創建方式,但是如果未創建該client
套接字,則應在進入此循環之前連接它。
BufferedOutputStream out = new BufferedOutputStream(client.getOutputStream());
BufferedInputStream in = new BufferedInputStream(client.getInputStream());
同樣,您必須在循環之前創建這些流。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.