gpt4 book ai didi

c# - 发送到 Java 套接字时 .Net 套接字阻塞

转载 作者:行者123 更新时间:2023-11-30 11:42:18 25 4
gpt4 key购买 nike

我有一个简单的 Java 服务器套接字,但是当我使用 C#.Net 套接字连接到它并发送到 Java 套接字时,它会阻塞,我必须关闭 .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();

最佳答案

首先,检查Available,因为循环退出条件是不安全的;告诉您的只是本地缓冲的内容;这与流的结尾无关。

其次,添加一个Thread.Sleep 并不是一个理想的方式;只是阅读或接收;这将阻塞直到一些数据可用;通常你只是循环读取或接收。

它会挂起的一个明显情况:如果另一台机器没有发送任何回复;在这种情况下,它将永远位于最顶层的循环中。

补充说明:

  • 不应该每次迭代都需要分配一个新的缓冲区;以前的 8192 缓冲区仍然可以;重新使用它
  • 不应该假设您的缓冲区中有完整的字符,尤其是因为您使用的是 UTF8;您的缓冲区可能包含字符的多字节表示的一部分;在开始解码之前确保您拥有完整的消息/帧通常更容易

就我个人而言,我会通过添加大量调试输出和网络嗅探器来对此进行调查。

关于c# - 发送到 Java 套接字时 .Net 套接字阻塞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11778634/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com