繁体   English   中英

C#客户端与C ++服务器通信-服务器可以从套接字读取,但写入不成功

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM