求助!c++ tcp send发数据,服务端接受不到,客户端关掉程序,服务端才能接收到??

cs365315634 2014-08-13 04:13:36
//启动服务
void MySocket::StartServer()
{

DWORD myMainThreadID=::GetCurrentThreadId(); //获取当前线程也就是主线程的ID号
static ThreadParameter tp;//此处需设置为静态变量
tp.MainThreadID=myMainThreadID;
HANDLE hThread = CreateThread(NULL,0,StartAcceptThread,(LPVOID)&tp,0,NULL);//创建新线程
CloseHandle(hThread);
}
//线程的启动函数
DWORD WINAPI MySocket::StartAcceptThread(LPVOID lpData)
{
ThreadParameter tp=*((ThreadParameter *)lpData);
int nServAddlen = sizeof(servAddr);
//初始化套结字动态库
if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
{
MessageBox(NULL,L"网络连接失败",L"Title(标题)",MB_OK);
return 1;
}
//创建套接字
sHost = socket(AF_INET, SOCK_STREAM, 0);

if(INVALID_SOCKET == sHost)
{
MessageBox(NULL,L"网络连接失败",L"Title(标题)",MB_OK);
cout << "socket failed!" << endl;
WSACleanup();//释放套接字资源
return 1;
}

//设置服务器地址
servAddr.sin_family =AF_INET;
servAddr.sin_addr.s_addr = inet_addr(CLIENT_HOST);
servAddr.sin_port = htons((short)CLIENT_PORT);



int sndbuf=0; /* Send buffer size */
//在发送数据的时,不执行由系统缓冲区到socket缓冲区的拷贝,以提高程序的性能
setsockopt( sHost, SOL_SOCKET, SO_SNDBUF, ( char * )&sndbuf, sizeof( sndbuf ) );

BOOL bNodelay = TRUE;
setsockopt( sHost, SOL_SOCKET, TCP_NODELAY, ( char* )&bNodelay, sizeof( BOOL ) );

//unsigned long on = 1;
// ioctlsocket(sHost, FIONBIO, &on);//将套接字设为非阻塞,on=1为非阻塞,on=0阻塞

//连接服务器
retVal=connect(sHost,(LPSOCKADDR)&servAddr, sizeof(servAddr));
if(SOCKET_ERROR == retVal)
{
cout << "connect failed!" << endl;
MessageBox(NULL,L"网络连接失败",L"Title(标题)",MB_OK);
closesocket(sHost); //关闭套接字
WSACleanup(); //释放套接字资源
return 1;
}
isFirst=true;//连接成功
receiveServerMessage(tp);//循环接收服务端发来的消息
return 1;
}

void MySocket:: MessageWillSend()
{
static ThreadParameter ctp;//此处需设置为静态变量
DWORD myMainThreadID=::GetCurrentThreadId(); //获取当前线程也就是主线程的ID号
ctp.MainThreadID=myMainThreadID;
HANDLE hThread = CreateThread(NULL,0,sendMessageThread,(LPVOID)&ctp,0,NULL);//创建新线程
CloseHandle(hThread);
}
//发送数据线程
DWORD WINAPI MySocket:: sendMessageThread(LPVOID lpData)
{
//判断是否连接成功
if(!isFirst)
{
MessageBox(NULL,L"网络连接失败",L"Title(标题)",MB_OK);
return 1;
}

ThreadParameter tp=*((ThreadParameter *)lpData);
EnterCriticalSection(&cs);//加锁
//向服务器发送数据
ZeroMemory(buf, BUF_SIZE);
string pp=MyTool:: UnicodeToUTF8(data);
strcpy(buf,pp.c_str());
ZeroMemory(data, BUF_SIZE);
LeaveCriticalSection(&cs);//解锁
retVal = send(sHost, buf, strlen(buf)+1, 0);

if (SOCKET_ERROR == retVal)
{
cout << "send failed!" << endl;
MessageBox(NULL,L"网络连接失败",L"Title(标题)",MB_OK);
closesocket(sHost); //关闭套接字
WSACleanup(); //释放套接字资源
return 1;
}
return 1;
}
//接受数据线程
void receiveServerMessage(ThreadParameter tp)
{
while(true)
{
ZeroMemory(bufRecv, BUF_SIZE);
size_t len =strlen(bufRecv)+1;
//iResult = recv(sHost, bufRecv, BUF_SIZE, 0);

if (recv(sHost,bufRecv,BUF_SIZE,0) == SOCKET_ERROR){
int id = WSAGetLastError();
switch (id)
{
case WSANOTINITIALISED:
printf("not initialized\n");
break;
case WSASYSNOTREADY:
printf("sub sys not ready\n");
break;
case WSAHOST_NOT_FOUND:
printf("name server not found\n");
break;
case WSATRY_AGAIN:
printf("server fail\n");
break;
case WSANO_RECOVERY:
printf("no recovery\n");
break;
case WSAEINPROGRESS:
printf("socket blocked by other prog\n");
break;
case WSANO_DATA:
printf("no data record\n");
break;
case WSAEINTR:
printf("blocking call canciled\n");
break;
case WSAEPROCLIM:
printf("limit exceeded\n");
break;
case WSAEFAULT:
printf("lpWSAData in startup not valid\n");
break;
case WSAECONNRESET:
MessageBox(NULL,L"服务端关闭连接",L"Title(消息提示)",MB_OK);
break;
default:

break;
};
return;//退出线程
};
wchar_t * msg=MyTool::UTF8ToUnicode(bufRecv);
wcout.imbue(locale("chs"));
copyData(msg);
//线程间通讯
if(PostThreadMessage(tp.MainThreadID,WM_PARTY_MSG,0,(LPARAM)bufRecv)==0)
{

}
}
}
...全文
511 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
心逸无名 2016-01-07
  • 打赏
  • 举报
回复
我也碰到了这个问题,TCP长连接,客户端能正常发送消息,服务端突然就接收不到消息了。排查了很久后,发现,客户端关闭后,所有前面发送的消息,服务端一次收到了!谁能解释下原因?感谢!!
赵4老师 2014-08-14
  • 打赏
  • 举报
回复
个人建议,调试TCP或UDP通讯程序之前先学会使用抓包软件比如wireshark
勤奋的小游侠 2014-08-14
  • 打赏
  • 举报
回复
用select IO。将receiveServerMessage的while循环去掉。只有select满足读条件时才去读。
cs365315634 2014-08-14
  • 打赏
  • 举报
回复
应该怎么改呢?
阿呆_ 2014-08-13
  • 打赏
  • 举报
回复
好奇怪的逻辑,把socket设置成unblock然后connect, recv, send都可能返回SOCKET_ERROR并且WSAGetLastError()会返回WSAEWOULDBLOCK,但是程序中并没有用select或 WSAAsyncSelect等异步socket的操作等待而是直接返回错误关闭线程了,那么你运气逆天的时候偶尔发送成功一次有什么可奇怪的?
cs365315634 2014-08-13
  • 打赏
  • 举报
回复
这就是 客户端的socket
勤奋的小游侠 2014-08-13
  • 打赏
  • 举报
回复
客户端的socket也设置成TCP_NODELAY

64,691

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧