![](/img/trans.png)
[英]Java(client) and C#(Server) TCP Socket. and Server read infinite last data from client
[英]C# client communicating with C++ server - server can read from socket but writing is unsuccessful
我的两个程序有问题-C#客户端可以使用套接字将数据成功写入C ++客户端,但是从服务器读取数据失败。
这是我的C ++代码:
int sock = socket(PF_INET, SOCK_STREAM, 0);
sockaddr_in sockad;
// sin_family, port etc defined here
bind(sock, (sockaddr*)&sockad, sizeof(sockad));
listen(sock, 15);
char buf;
stringstream ss;
while(running) {
socklen_t sockl = sizeof(sockad);
int sockd = accept(sock, (sockaddr*)&sockad, &sockl);
while(recv(sockd, &buf, 1, 0) > 0) {
ss << buf;
}
// THIS is printed
cout << ss.str() << endl;
string response = "asdgfh";
// THIS never reaches the C# client
write(sockd, response.c_str(), strlen(response.c_str()));
close(sockd);
}
close(sock);
这是我的C#代码:
string message = "message";
Int32 port = 4345;
TcpClient client = new TcpClient("server.address.com", port);
NetworkStream stream = client.getStream();
Byte[] data = new Byte[256];
data = Encoding.ASCII.GetBytes(message);
// THIS SUCCEEDS
stream.Write(data, 0, data.Length);
// THIS FAILS, it also freezes the other program
Int32 bytes = stream.Read(data, 0, data.Length);
responseData = Encoding.ASCII.GetString(data, 0, bytes);
stream.Close();
client.Close();
那么我的代码出了什么问题,或者这是服务器配置问题还是类似的问题?
问题是典型的死锁。
在C ++端,您一直从套接字读取数据,直到TCP连接被(半断开)为止。 在C#端,您要写入一些数据,然后等待TCP连接被(半关闭) 。 双方均未关闭连接,因此两个程序都必须在各自的读取/接收过程中阻塞,直到其他原因破坏了通信。 从根本上讲,这意味着“拔出网络电缆”,因为默认情况下TCP不会执行任何心跳操作。
您需要了解有关TCP的两件事。 首先,TCP是基于流的协议,而不是基于消息的协议。 这意味着,如果要通过TCP发送消息,则需要添加自己的框架-在TCP流的顶部构建自己的消息传递协议。 您假设C#端的写入将神奇地与C ++端的读取相对应,但这完全不是TCP的工作方式。
其次, 只有在流关闭时,读/接收才返回零。 这与TCP是基于流的协议紧密结合-如果您仅等待一点时间填充缓冲区,就会假装有无限数量的数据要读取。
该问题主要有两种解决方案。 首先是要确保在继续写入之前仅阅读一条消息。 简单的方法是在发送的“消息”前面加上长度,以便C ++端知道当读取N个字节后,它便拥有了所需的所有数据并且可以继续下去。 第二个是使用异步I / O同时读取和写入。 始终有未完成的读取请求,并对读取的内容做出反应,而不是尝试进行读写读写顺序代码。
如果您只需要类似于HTTP的请求-响应模式,则也可以仅部分关闭套接字。 您可以使用TcpClient.Client.Shutdown(SocketShutdown.Send)
在C#端执行此操作。 然后,这两个应用程序将可以自由继续处理响应。 当然,响应处理完成后,您再次想要从C ++端关闭。 结果是双方之间都处于封闭连接,并且整个请求-响应周期也是如此。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.