我使用一个c程序来响应API调用。我想使用JSON进行回复。我在端口上创建了一个流套接字,并使用浏览器创建了一个GET请求(在我的例子中是firefox)。然后根据收到的请求使用"send“方法进行答复。
问题是当我的答复大于29200字节时。然后发送方法返回29200,只发送前29200字节,然后停止。我不明白为什么会停在这个号码上。
我尝试了google并发现:C++ socket programming Max size of TCP/IP socket Buffer?
我的套接字是阻塞的,所以send()函数应该阻塞,直到所有数据都被发送为止。
我还试图查找linux是否阻塞任何东西,但当我检查(不确定我是如何检查的,无法找到描述此问题的堆栈溢出问题)时,它被设置为比29200大得多的东西。
我想知道为什么我的套接字停止在29200,如果可能的话,我如何可以改变套接字,使它发送更多的数据?
编辑:
对以下结果进行了测试:
创建了一个只发送29999字节数据的测试程序:https://pastebin.ca/4010317
我使用curl来接收数据,使用curl -X GET -i 'http://:12345‘
在我的计算机上运行时,响应是:
received: -1 bytes
received:
sent 29999 bytes我可以看到,在我的计算机(x64)上,接收不工作,但发送确实工作(Curl确实接收数据)
但是,当在ARM设备上运行时,响应是:
received: 83 bytes
received: GET / HTTP/1.1
Host: 192.168.1.118:12345
User-Agent: curl/7.47.0
Accept: */*
J
sent 29200 bytes在这里,curl接收29200字节的数据。
当尝试循环发送(https://pastebin.ca/4010318)时,结果是:
received: -1 bytes
received:
sent 29199 bytes在这里,curl接收29200字节,第二次发送返回-1。所以循环是不可能的。
我会继续努力,但我们会感谢你的帮助。
发布于 2018-04-03 16:14:17
我终于发现了问题,问题是
accept4(socket, (struct sockaddr *) &addrInfoFromClient, &sizeAddrInfo, SOCK_NONBLOCK); 将套接字设置为非阻塞,而在init中,套接字设置为阻塞。在ARM设备上,这导致“写”函数在29200字节后停止写入(不确定原因)。
当我将accept4更改为:
accept(socket, (struct sockaddr *) &addrInfoFromClient, &sizeAddrInfo);啊,真灵。
发布于 2018-04-03 10:00:31
你的代码有效。准确地说,尽管有很多小的误用函数,它还是有效的。
首先,我问您一个mvce :您给出的代码包含一些无用的代码,这些代码只增加了复杂性:如果您不需要客户端连接的信息,则可以传递NULL来接受。
accept4(socketId, NULL, NULL, SOCK_NONBLOCK);这样,我们就没有2个无用的变量。
第二:检查错误是很酷的,但是显示一些东西(或日志记录)更好,因为您可以知道为什么这不起作用。
例如,您解释为不工作的“接收:-1字节”实际上是工作的:错误(errno)是EAGAIN,这意味着由于您的套接字是非阻塞的,因此数据当前不可用,因此您必须循环recv来读取incomming数据。循环恢复将“解决”您的错误问题。
最后:不,您也不能循环发送:您只需检测是否还没有发送所有数据,然后再试一次:执行循环!
编辑:
您可以看到我如何为"check error and logging“部分执行"initServerSocket”函数:
int InitServerSocket(int portNum, int nbClientMax)
{
int socketId = -1;
struct sockaddr_in addressInfo;
int returnFunction = -1;
if ((socketId = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
// Log !
goto END_FUNCTION;
}
addressInfo.sin_family = AF_INET;
addressInfo.sin_addr.s_addr = htonl(INADDR_ANY);
addressInfo.sin_port = htons(portNum);
if (bind(socketId, (struct sockaddr *)&addressInfo, sizeof(addressInfo)) == -1) {
// Log !
goto END_FUNCTION;
}
const int flags = fcntl(socketId, F_GETFL, 0);
fcntl(socketId, F_SETFL, flags ^ O_NONBLOCK);
// Error detection & log ?
if (listen(socketId, nbClientMax) == -1) {
// Log !
goto END_FUNCTION;
}
returnFunction = socketId;
socketId = -1;
/* GOTO */END_FUNCTION:
if (socketId != -1) {
close(socketId);
}
return (returnFunction);
}https://stackoverflow.com/questions/49571963
复制相似问题