C++ 套接字发送()在发送一定数量的字节后挂起
我想向我的nodejs TCP服务器发送一个字符串 这是我的客户机(C++)的代码: 问题来了: 客户端只发送大约180条消息,然后C++ 套接字发送()在发送一定数量的字节后挂起,c++,sockets,tcp,C++,Sockets,Tcp,我想向我的nodejs TCP服务器发送一个字符串 这是我的客户机(C++)的代码: 问题来了: 客户端只发送大约180条消息,然后send挂起。服务器仅接收约120条消息。当我增加请求的长度时,客户端发送的请求较少,而当我减少请求的长度时,客户端发送的请求较多。我还发现,当我减少发送间隔时,我可以在send挂起之前发送更多请求。我不知道我做错了什么。当我用NoDEJS客户端执行类似的代码时,一切都正常,所以问题在于C++客户端。 编辑: 我并不认为这是必要的,但下面是connectToServ
send
挂起。服务器仅接收约120条消息。当我增加请求的长度时,客户端发送的请求较少,而当我减少请求的长度时,客户端发送的请求较多。我还发现,当我减少发送间隔时,我可以在send
挂起之前发送更多请求。我不知道我做错了什么。当我用NoDEJS客户端执行类似的代码时,一切都正常,所以问题在于C++客户端。
编辑:
我并不认为这是必要的,但下面是connectToServer()的代码
< > C++客户端输出(发送间隔:2000毫秒,MSGLIGH:126~127字符):
来自nodejs服务器的输出(仅接收9条消息):
测试结果以查看发送间隔、消息长度和发送消息数之间是否存在连接:
connection data from ip::port: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ12345678900
...keeps going on for a while...
connection data from ip::port: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ12345678909
sendInterval | msgLength | nMsg
---------------------------------------
200 | 127 | 26
200 | 65 | 33
---------------------------------------
400 | 65 | 59
400 | 127 | 53
---------------------------------------
2000 | 65 | 47
2000 | 127 | 21
发送间隔| msgLength | nMsg
---------------------------------------
200 | 127 | 26
200 | 65 | 33
---------------------------------------
400 | 65 | 59
400 | 127 | 53
---------------------------------------
2000 | 65 | 47
2000 | 127 | 21
(我看不出这些值之间有什么联系)正如我所见,您应该注意一些问题:
您正试图将许多消息发送到客户的
代码,但使用
变量sendResult
。在发送另一个之前,应该检查它
信息
您使用同一个线程发送数据并检查发送每条消息的时间间隔,这会消耗大量CPU。我建议创建一个线程(TSync)来参加sleep
或std::chrono
的间隔,并调用一个通过套接字发送消息的方法,但不在同一个线程TSync中,因为您将使用sleeps阻塞套接字
最后,您应该使用FD_SET
和select
检查何时可以通过套接字发送数据,何时套接字可以发送更多字节
可能是您在没有控制的情况下发送消息的方式影响了TX通道,因为TX通道已满,因此您应该使用FD_SET
控制输出操作,并选择以与套接字同步。在write的情况下,表示:
选择功能用于确定一个或多个套接字的状态。对于每个套接字,调用方可以请求有关读取、写入或错误状态的信息
writefds:可以发送数据
更新,4月21日:我建议您分享有关您的问题的更多信息,如服务器的代码和配置,以了解是否存在超时配置或缓冲区大小。提供给您的信息不够,并且不要低估我们向您提出的请求,如以下评论:
我并不认为这是必要的,但下面是connectToServer()的代码:
连接过程很重要,因为我们可以看到套接字服务器是否设置了一些选项
在这种情况下,您与我们共享的所有信息都会有所帮助,而不是假设这些信息并不重要
所以,在这个时刻,这就是我能帮助你的全部
4月24日更新:尝试以下步骤控制套接字传输并设置非阻塞套接字:
- 成功连接后,在客户端中,将套接字设置为非阻塞
- 使用循环文件描述符(
FD_SET
)和选择来检查套接字何时准备好写入
您的代码应包含以下代码:
void ConnectToServer()
{
//... your code
int connectResult = ::connect(sock, (struct sockaddr *)&server, sizeof(server));
if (connectResult >= 0)
{
u_long iMode = 1;
int iResult = ioctlsocket(sock, FIONBIO, &iMode); //Set the socket Non-Blocking
printf("Connected to server!\n");
}
else
{
printf("Not connected to server. Err: %d\n", connectResult);
}
}
int main(){
Connect(); //function to connect with a WiFi network
ConnectToServer();
unsigned long lastSendTime = 0;
unsigned long sendInterval = 200; //send a message every 200 milliseconds
unsigned int nMsgSent = 0;
fd_set write_fd;
while (1){
unsigned long now = milliseconds(); //function to get the time in milliseconds
if ((now - lastSendTime) > sendInterval){
std::string request = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
request += request;
request += std::to_string(nMsgSent);
request += "\n";
FD_ZERO(&write_fd); //Reset the File Descriptor
FD_SET(sock, &write_fd); //Set se File descriptor to the socket.
int result = select(max_sd, NULL, &write_fd, NULL, NULL); //Wait until the socket is ready to write
if (result < 0)
{
iprintf("There was a problem with the sockets reading.\n");
FD_ZERO(&write_fd);
}
int sendResult = ::send(sock, request.c_str(), request.length(), 0);
iprintf("req(%d): %d\n", nMsgSent, sendResult);
nMsgSent++;
lastSendTime = now;
}
}
return 0;
}
void ConnectToServer()
{
//…您的代码
int connectResult=::connect(sock,(struct sockaddr*)和server,sizeof(server));
如果(连接结果>=0)
{
u_long iMode=1;
int-iResult=ioctlsocket(sock、FIONBIO和iMode);//将套接字设置为非阻塞
printf(“已连接到服务器!\n”);
}
其他的
{
printf(“未连接到服务器。错误:%d\n”,connectResult);
}
}
int main(){
Connect();//用于连接WiFi网络的函数
ConnectToServer();
无符号长lastSendTime=0;
unsigned long sendInterval=200;//每200毫秒发送一条消息
无符号整数nMsgSent=0;
fd_集写_fd;
而(1){
unsigned long now=毫秒();//函数以毫秒为单位获取时间
如果((现在-上次发送时间)>发送间隔){
std::string request=“abcdefghijklmnopqrstuvxyzabcdefghijklmnopqrstuvxyz1234567890”;
请求+=请求;
请求+=std::to_字符串(nMsgSent);
请求+=“\n”;
FD_ZERO(&write_FD);//重置文件描述符
FD_SET(sock,&write_FD);//将se文件描述符设置为套接字。
int result=select(max_sd,NULL,&write_fd,NULL,NULL);//等待套接字准备好写入
如果(结果<0)
{
iprintf(“套接字读取有问题。\n”);
FD_ZERO(&write_FD);
}
int sendResult=::发送(sock,request.c_str(),request.length(),0);
iprintf(“请求(%d):%d\n”、nMsgSent、sendResult);
nMsgSent++;
lastSendTime=现在;
}
}
返回0;
}
不要发送垃圾标签!这不是C。C不是C++不是C!@Olaf我知道,但套接字库是C代码,对吗?@user7353781套接字库的语言与您的问题无关。如果客户端发送消息的速度快于服务器读取消息的速度,则clie
req(1): 126
req(2: 126
req(3): 126
...keeps going on for a while...
req(9): 126
req(10): 126
req(11): 127
req(12): 127
...keeps going on for a while...
req(74): 64
send() hangs after this
connection data from ip::port: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ12345678900
...keeps going on for a while...
connection data from ip::port: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ12345678909
sendInterval | msgLength | nMsg
---------------------------------------
200 | 127 | 26
200 | 65 | 33
---------------------------------------
400 | 65 | 59
400 | 127 | 53
---------------------------------------
2000 | 65 | 47
2000 | 127 | 21
void ConnectToServer()
{
//... your code
int connectResult = ::connect(sock, (struct sockaddr *)&server, sizeof(server));
if (connectResult >= 0)
{
u_long iMode = 1;
int iResult = ioctlsocket(sock, FIONBIO, &iMode); //Set the socket Non-Blocking
printf("Connected to server!\n");
}
else
{
printf("Not connected to server. Err: %d\n", connectResult);
}
}
int main(){
Connect(); //function to connect with a WiFi network
ConnectToServer();
unsigned long lastSendTime = 0;
unsigned long sendInterval = 200; //send a message every 200 milliseconds
unsigned int nMsgSent = 0;
fd_set write_fd;
while (1){
unsigned long now = milliseconds(); //function to get the time in milliseconds
if ((now - lastSendTime) > sendInterval){
std::string request = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
request += request;
request += std::to_string(nMsgSent);
request += "\n";
FD_ZERO(&write_fd); //Reset the File Descriptor
FD_SET(sock, &write_fd); //Set se File descriptor to the socket.
int result = select(max_sd, NULL, &write_fd, NULL, NULL); //Wait until the socket is ready to write
if (result < 0)
{
iprintf("There was a problem with the sockets reading.\n");
FD_ZERO(&write_fd);
}
int sendResult = ::send(sock, request.c_str(), request.length(), 0);
iprintf("req(%d): %d\n", nMsgSent, sendResult);
nMsgSent++;
lastSendTime = now;
}
}
return 0;
}