我有一个简单的Java Server Socket但是当我使用C#.Net Socket和发送到Java Socket连接它时它会阻塞,我必须关闭.Net套接字发送它才能阻止它。这意味着我必须在每次通信后关闭套接字。我哪里错了?
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint ip = new IPEndPoint(IPAddress.Parse(ipAddress.Text), 8089);
socket.Connect(ip);
byte[] b = Encoding.UTF8.GetBytes(json);
socket.Send(b, b.Length, SocketFlags.None);
socket.Shutdown(SocketShutdown.Send);
int timeout = 0;
while (socket.Available == 0)
{
Thread.Sleep(100);
timeout++;
}
string response = "";
byte[] buffer = new byte[8192];
int total = 0;
while (socket.Available > 0)
{
int len = socket.Receive(buffer);
total += len;
response = response + (Encoding.UTF8.GetString(buffer, 0, len));
buffer = new byte[1024];
if (socket.Available == 0) Thread.Sleep(250);
}
MessageBox.Show(response);
return response.Trim();
}
服务器侧
clientSocket = serverSocket.accept();
clientSocket.setKeepAlive(true);
Log.d("DbThread","client Connected");
br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()),8192);
bo = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()),8192);
Thread.sleep(100);
char[] buffer = new char[8192];
int len=0;
String build = "";
while((len = br.read(buffer))>0){
build = build + new String(buffer);
buffer = new char[8192];
}
JSONObject json = new JSONObject(build.trim());
Log.d("input",build.trim());
String output = "";
Gson gson = new Gson();
switch(json.getString("classType").charAt(0))
{
case 'Q':
Log.d("classType","Q");
Query query = gson.fromJson(build.trim(), Query.class);
output = query.executeToJson();Log.d("Query","end");break;
case 'I':
Log.d("classType","I");
Insert insert = gson.fromJson(build.trim(), Insert.class);
output = insert.executeToJson();break;
case 'U':
Log.d("classType","U");
Update update = gson.fromJson(build.trim(), Update.class);
output = update.executeToJson();break;
case 'D':
Log.d("classType","D");
Delete delete = gson.fromJson(build.trim(), Delete.class);
output = delete.executeToJson();break;
}
bo.write(output);
bo.flush();
Log.d("Query",output);
br.close();
答案 0 :(得分:1)
首先,将Available
视为循环退出条件是不安全的;所有这些都告诉你本地缓冲的是什么;这与流的结束无关。
其次,添加Thread.Sleep
并不是理想的做法;只是阅读或接受;这将阻止某些数据可用;通常你只是在阅读或接收上循环。
一个明显的情况,它将挂起:如果其他机器没有发送任何回复;在这种情况下,它将永远位于最顶层的循环中。
附加说明:
buffer
;以前的8192缓冲区仍然没问题;重复使用我个人会通过添加大量调试输出和网络嗅探器来研究这个问题。