问题描述
我使用正常(?)步骤进行了 tcp 套接字连接,如下面的代码所示.但是发送 有时 导致 10057 错误,而服务器端打印了一些表示连接已进入的日志,我不知道我的代码有什么问题.任何帮助表示赞赏.感谢有关稳定和健壮的 Windows 套接字编程的任何信息.
I did tcp socket connection with normal(?) steps as the code shows below. But send sometimes result in 10057 error while server-end printed some log which says connection is in, I have no idea about what's wrong with my code. Any help is appreciated. Any information about stable and robust windows socket programming is appreciated.
MSDN 关于 10057 错误的描述:
MSDN description about 10057 error:
套接字未连接.发送或接收数据的请求被禁止,因为套接字未连接并且(使用 sendto 在数据报套接字上发送时)未提供地址.任何其他类型的操作也可能返回此错误 - 例如,如果连接已重置,则设置 SO_KEEPALIVE.
PS:下面代码片段中的真实 ip 地址被替换为 127.0.0.1.代码无法运行.
int connect_to_server() {
SOCKET soc;
SOCKADDR_IN serveraddr;
SOCKADDR_IN clientaddr;
unsigned char buf[1024];
WSADATA wsa;
WSAStartup(MAKEWORD(2, 2), &wsa);
/* create a tcp socket; */
if ((soc = socket(AF_INET, SOCK_STREAM, 0/*IPPROTO_TCP*/)) <= 0)
{
LOGFMTF("errcode[-1], create socket fail!");
return -1;
}
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons(9102);
serveraddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
unsigned long mode = 1; // 1 to enable non-blocking socket
if (ioctlsocket(soc, FIONBIO, &mode) == SOCKET_ERROR) {
LOGFMTF("errcode[-2], ioctlsocket fail.");
return -2;
}
if (::connect(soc, (SOCKADDR *)&serveraddr, sizeof(serveraddr)) != 0)
{
/* FIONBIO socket enters here can go run; non-FIONBIO socket enters here stands for real error;*/
if (WSAGetLastError() != WSAEWOULDBLOCK) {
LOGFMTF("errcode[-3], connect fail.");
//return -3;
}
//return -1;
}
g_client_fd = soc;
LOGFMTT("client_fd[%d]", g_client_fd);
LOGFMTT("connect to server last err[%d].", WSAGetLastError());
return 0;
}
/** send loop; */
DWORD WINAPI send_thread_loop(LPVOID pM) {
LOGFMTT("send thread[%d] start.", GetCurrentThreadId());
for (;!g_to_exit;)
{
QMutexLocker locker(&g_send_queue_lock);
if (g_send_queue.count() == 0) {
Sleep(Send_Thread_Gap);
}else {
LOGFMTT("send one packet.");
int pakcet_size = g_send_queue.begin()->size;
char *addr = g_send_queue.begin()->data;
::send(g_client_fd, addr, pakcet_size, 0);
/* ------------!Attention begin------------ */
LOGFMTT("send last err[%d].", GetLastError());--------> sometimes got 10057 error.
/* ------------!Attention end------------ */
delete[]addr;
g_send_queue.erase(g_send_queue.begin());
}
}
LOGFMTT("send thread[%d] exit.", GetCurrentThreadId());
return 0;
}
int start_net_thread() {
g_recv_thread = CreateThread(NULL, 0, recv_thread_loop, NULL, 0, NULL);
g_send_thread = CreateThread(NULL, 0, send_thread_loop, NULL, 0, NULL);
return 0;
}
int main(){
if(connect_to_server() != 0)
{
QMessageBox msgBox;
msgBox.setText("failed.");
msgBox.exec();
return -1;
}
start_net_thread();
return 0;
}
推荐答案
它没有.至少,没有证据表明确实如此.
It didn't. At least, there is no evidence that it did.
::send(g_client_fd, addr, pakcet_size, 0);
/* ------------!Attention begin------------ */
LOGFMTT("send last err[%d].", GetLastError());--------> sometimes got 10057 error.
调用 WSAGetLastError()
是无效的code>send() 返回 -1.但是由于您没有检查这一点,因此这里没有证据表明有问题需要解决,除了您围绕 send()
的糟糕编码.它应该是:
It isn't valid to call WSAGetLastError()
unless there was an error, which in this case would have been signalled by send()
returning -1. But as you aren't checking for that, there is no evidence here of a problem to be solved, except for your poor coding around send()
. It should read:
if (::send(g_client_fd, addr, pakcet_size, 0) == -1)
{
/* ------------!Attention begin------------ */
LOGFMTT("send last err[%d].", GetLastError());--------> sometimes got 10057 error.
}
注意这个词拼写为packet",而不是pakcet".
NB The word is spelt 'packet', not 'pakcet'.
这篇关于为什么我的 winsocks2 发送结果有时会出现 10057 错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!