我用TCP/IP建立了C/S结构。
客户端首先发数据,服务端等40MS后给客户端发数据。
客户端没100MS检查是否收到数据,收到就给服务器发。
循环执行。大部分情况都很好,只是出现一个怪现象。
没隔10分钟,就会出现收不到数据的情况。发现每隔10分钟,SOCKET会缓存几拍一起发送。我已经设置SOKET为NO_DELAY发送了,还是不行。各位大虾,给点意见吧。服务端建立程序如下:
/* The WinSock DLL is acceptable. Proceed. */
GROUP g = 0;
//
sServer = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_IP, NULL, g, 0);
//sServer = WSASocket(AF_INET, SOCK_RAW, IPPROTO_RAW, NULL, 0, WSA_FLAG_OVERLAPPED); //创建套接字
sockaddr_in sockAddr;
memset(&sockAddr, 0, sizeof(sockaddr_in));
sockAddr.sin_family = AF_INET;
sockAddr.sin_port = htons(SerPort);
sockAddr.sin_addr.S_un.S_addr = inet_addr(IPAddr);
int ret = bind(sServer, (sockaddr*)(&sockAddr), sizeof(sockaddr_in)); if (ret != 0)
{
return CTEC_BINDERR;
}
else
{
DWORD dwBytesReturned = 0;
BOOL bNewBehavior = TRUE; //ture 非阻塞 false 阻塞
DWORD status;
// disable new behavior using
// IOCTL: SIO_UDP_CONNRESET
status = WSAIoctl(sServer, FIONBIO,
&bNewBehavior, sizeof(bNewBehavior),
NULL, 0, &dwBytesReturned,
NULL, NULL); if (SOCKET_ERROR == status)
{
DWORD dwErr = WSAGetLastError();
if (WSAEWOULDBLOCK == dwErr)
{
// nothing to do
return 0;
}
else
{
return 0;
}
} int killnagle = 0;
int result = setsockopt(sServer, IPPROTO_IP, TCP_NODELAY, (const char*)&killnagle, sizeof(int)); if (result != 0)
{
return 0;
} setsockopt(sServer,SOL_SOCKET,SO_SNDBUF,(const char*)&nSendBuf,sizeof(int));
setsockopt(sServer,SOL_SOCKET,SO_RCVBUF,(const char*)&nRecvBuf,sizeof(int));
listen(sServer, 1);客户端建立如下:
GROUP g = 0;
// sClient = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, g, 0);
sClient = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_IP, NULL, g, 0); sockaddr_in dstAddr;
dstAddr.sin_family = AF_INET;
dstAddr.sin_addr.S_un.S_addr = inet_addr(sServerAddr);
dstAddr.sin_port = htons(uSerPort); int ret = WSAConnect(sClient, (sockaddr*)(&dstAddr), sizeof(SOCKADDR), NULL, NULL,NULL, NULL ); if (ret == 0)
{
pClientRecvBuffer = new char[MAX_DATA_LEN];
memset(pClientRecvBuffer, 0, MAX_DATA_LEN);
DWORD dwBytesReturned = 0;
BOOL bNewBehavior = TRUE; //ture Not blocking false blocking
DWORD status;
// disable new behavior using
// IOCTL: SIO_UDP_CONNRESET
status = WSAIoctl(sClient, FIONBIO,
&bNewBehavior, sizeof(bNewBehavior),
NULL, 0, &dwBytesReturned,
NULL, NULL); if (SOCKET_ERROR == status)
{
DWORD dwErr = WSAGetLastError();
if (WSAEWOULDBLOCK == dwErr)
{
// nothing to do
return 0;
}
else
{
return 0;
}
} int killnagle = 0;
int result = setsockopt(sClient, IPPROTO_IP, TCP_NODELAY, (const char*)&killnagle, sizeof(int)); if (result != 0)
{
return 0;
} setsockopt(sClient,SOL_SOCKET,SO_SNDBUF,(const char*)&nSendBuf,sizeof(int));
setsockopt(sClient,SOL_SOCKET,SO_RCVBUF,(const char*)&nRecvBuf,sizeof(int));
客户端首先发数据,服务端等40MS后给客户端发数据。
客户端没100MS检查是否收到数据,收到就给服务器发。
循环执行。大部分情况都很好,只是出现一个怪现象。
没隔10分钟,就会出现收不到数据的情况。发现每隔10分钟,SOCKET会缓存几拍一起发送。我已经设置SOKET为NO_DELAY发送了,还是不行。各位大虾,给点意见吧。服务端建立程序如下:
/* The WinSock DLL is acceptable. Proceed. */
GROUP g = 0;
//
sServer = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_IP, NULL, g, 0);
//sServer = WSASocket(AF_INET, SOCK_RAW, IPPROTO_RAW, NULL, 0, WSA_FLAG_OVERLAPPED); //创建套接字
sockaddr_in sockAddr;
memset(&sockAddr, 0, sizeof(sockaddr_in));
sockAddr.sin_family = AF_INET;
sockAddr.sin_port = htons(SerPort);
sockAddr.sin_addr.S_un.S_addr = inet_addr(IPAddr);
int ret = bind(sServer, (sockaddr*)(&sockAddr), sizeof(sockaddr_in)); if (ret != 0)
{
return CTEC_BINDERR;
}
else
{
DWORD dwBytesReturned = 0;
BOOL bNewBehavior = TRUE; //ture 非阻塞 false 阻塞
DWORD status;
// disable new behavior using
// IOCTL: SIO_UDP_CONNRESET
status = WSAIoctl(sServer, FIONBIO,
&bNewBehavior, sizeof(bNewBehavior),
NULL, 0, &dwBytesReturned,
NULL, NULL); if (SOCKET_ERROR == status)
{
DWORD dwErr = WSAGetLastError();
if (WSAEWOULDBLOCK == dwErr)
{
// nothing to do
return 0;
}
else
{
return 0;
}
} int killnagle = 0;
int result = setsockopt(sServer, IPPROTO_IP, TCP_NODELAY, (const char*)&killnagle, sizeof(int)); if (result != 0)
{
return 0;
} setsockopt(sServer,SOL_SOCKET,SO_SNDBUF,(const char*)&nSendBuf,sizeof(int));
setsockopt(sServer,SOL_SOCKET,SO_RCVBUF,(const char*)&nRecvBuf,sizeof(int));
listen(sServer, 1);客户端建立如下:
GROUP g = 0;
// sClient = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, g, 0);
sClient = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_IP, NULL, g, 0); sockaddr_in dstAddr;
dstAddr.sin_family = AF_INET;
dstAddr.sin_addr.S_un.S_addr = inet_addr(sServerAddr);
dstAddr.sin_port = htons(uSerPort); int ret = WSAConnect(sClient, (sockaddr*)(&dstAddr), sizeof(SOCKADDR), NULL, NULL,NULL, NULL ); if (ret == 0)
{
pClientRecvBuffer = new char[MAX_DATA_LEN];
memset(pClientRecvBuffer, 0, MAX_DATA_LEN);
DWORD dwBytesReturned = 0;
BOOL bNewBehavior = TRUE; //ture Not blocking false blocking
DWORD status;
// disable new behavior using
// IOCTL: SIO_UDP_CONNRESET
status = WSAIoctl(sClient, FIONBIO,
&bNewBehavior, sizeof(bNewBehavior),
NULL, 0, &dwBytesReturned,
NULL, NULL); if (SOCKET_ERROR == status)
{
DWORD dwErr = WSAGetLastError();
if (WSAEWOULDBLOCK == dwErr)
{
// nothing to do
return 0;
}
else
{
return 0;
}
} int killnagle = 0;
int result = setsockopt(sClient, IPPROTO_IP, TCP_NODELAY, (const char*)&killnagle, sizeof(int)); if (result != 0)
{
return 0;
} setsockopt(sClient,SOL_SOCKET,SO_SNDBUF,(const char*)&nSendBuf,sizeof(int));
setsockopt(sClient,SOL_SOCKET,SO_RCVBUF,(const char*)&nRecvBuf,sizeof(int));
解决方案 »
- BHO里可以使用FindResource()函数吗?
- 帮你高质高效并舒适地编程的工具:Visual Unit发布,试用获赠正式版!
- 向要用VC操作XML文件如何做
- DLL的调用问题,请问网络高手和系统编程高手~`
- 如果得到我在ClistBox中选中的多行
- 请哪位大哥大姐帮帮我
- 微软专家:What is IL(in .NET)? Are all managed code compiled to IL?
- 当系统进入到一个涵数后或一个类的成员涵数后,系统要做哪些工作,为它分配哪些资源
- (ahphone)阿丰哥!!! 你在那里!!!
- Tapi1.4中遇到的问题,请大家帮我
- CButton上的字如何竖着排列
- tcp连接 出现 10054错误
就两台电脑,1个HUB,相连。数据量在100K左右。10分钟的规律最疑惑了,用UDP也是这种效果,10分钟必丢一包。
nSendBuf = 1024*1024
nRecvBuf = 1024*1024
setsockopt(sClient,SOL_SOCKET,SO_SNDBUF,(const char*)&nSendBuf,sizeof(int));
setsockopt(sClient,SOL_SOCKET,SO_RCVBUF,(const char*)&nRecvBuf,sizeof(int));如果改成:
nSendBuf = 0
nRecvBuf = 0
setsockopt(sClient,SOL_SOCKET,SO_SNDBUF,(const char*)&nSendBuf,sizeof(int));
setsockopt(sClient,SOL_SOCKET,SO_RCVBUF,(const char*)&nRecvBuf,sizeof(int));根本就通不起来,发送和接收都非常缓慢。
#define INFO_SIZE 50
#define MAX_DATA_LEN (500*1024)
#define RECV_ONE_PACKET (500*1024)const int nSendBuf = 1024*1024;
const int nRecvBuf = 1024*1024;HANDLE hExitEvent = NULL;char *pServerRecvBuffer = NULL;
int g_iServerRecvLen = 0;
char *pClientRecvBuffer = NULL;
int g_iClientRecvLen = 0;BOOL bSvrDataOK = FALSE;
BOOL bClientDataOK = FALSE;SOCKET sServer = INVALID_SOCKET;
SOCKET sServer_Connected = INVALID_SOCKET;
SOCKET sClient = INVALID_SOCKET;DWORD WINAPI AcceptThread(LPVOID lpParam);
DWORD WINAPI SvrRecvThread(LPVOID lpParam);
DWORD WINAPI ClientRecvThread(LPVOID lpParam);BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
//初始化TCP/IP
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 2, 2 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
/* Tell the user that we could not find a usable */
/* WinSock DLL. */
return 1;
}
/* Confirm that the WinSock DLL supports 2.2.*/
/* Note that if the DLL supports versions greater */
/* than 2.2 in addition to 2.2, it will still return */
/* 2.2 in wVersion since that is the version we */
/* requested. */
if ( LOBYTE( wsaData.wVersion ) != 2 ||
HIBYTE( wsaData.wVersion ) != 2 ) {
/* Tell the user that we could not find a usable */
/* WinSock DLL. */
WSACleanup( );
return 1;
} //退出事件
hExitEvent = CreateEvent(NULL,FALSE,FALSE,NULL); return TRUE;
}void CALLBACK OnAccept(UINT wTimerID, UINT msg, DWORD dwUser, DWORD dw1, DWORD dw2)
{
SetEvent((HANDLE)dwUser);
} DWORD WINAPI AcceptThread(LPVOID lpParam)
{
TIMECAPS tc;
MMRESULT mmres;
if ( timeGetDevCaps(&tc,sizeof(tc))!=TIMERR_NOERROR )
{
FILE* fp = NULL;
fp = fopen(".\\TCP_CTEC.log","a+");
char info[INFO_SIZE];
memset(info, 0, INFO_SIZE);
sprintf(info, "%s\n", "Can't get accept multimedia timer resolution");
fwrite(info,1,INFO_SIZE,fp);
fclose(fp);
fp = NULL;
return 0;
}
HANDLE hSleep = CreateEvent(NULL,FALSE,FALSE,NULL); if ( !(mmres=timeSetEvent(1000, tc.wPeriodMin, OnAccept, (DWORD)hSleep, TIME_PERIODIC)))
{
return 0;
} while (1)
{
int iExit = WaitForSingleObject(hExitEvent,0);
if(iExit==WAIT_OBJECT_0)
{
break;
} DWORD res = WaitForMultipleObjects(1,&hSleep,FALSE,INFINITE);
sockaddr_in srcAddr;
int nAddrLen = sizeof(sockaddr);
SOCKET sAccetpTemp = WSAAccept(sServer, (sockaddr*)(&srcAddr), &nAddrLen, NULL, 0);
if (sAccetpTemp != INVALID_SOCKET)
{
sServer_Connected = sAccetpTemp;
setsockopt(sServer_Connected,SOL_SOCKET,SO_SNDBUF,(const char*)&nSendBuf,sizeof(int));
setsockopt(sServer_Connected,SOL_SOCKET,SO_RCVBUF,(const char*)&nRecvBuf,sizeof(int));
}
} timeKillEvent(mmres);
CloseHandle(hSleep);
hSleep = NULL; return 1;
}
void CALLBACK OnSvrRecv(UINT wTimerID, UINT msg, DWORD dwUser, DWORD dw1, DWORD dw2)
{
SetEvent((HANDLE)dwUser);
} DWORD WINAPI SvrRecvThread(LPVOID lpParam)
{
//设置1毫秒定时器
TIMECAPS tc;
MMRESULT mmres;
if ( timeGetDevCaps(&tc,sizeof(tc))!=TIMERR_NOERROR )
{
FILE* fp = NULL;
fp = fopen(".\\TCP_CTEC.log","a+");
char info[INFO_SIZE];
memset(info, 0, INFO_SIZE);
sprintf(info, "%s\n", "Can't get svr recv multimedia timer resolution");
fwrite(info,1,INFO_SIZE,fp);
fclose(fp);
fp = NULL;
return 0;
}
//设置事件
HANDLE hSleep = CreateEvent(NULL,FALSE,FALSE,NULL);
//启动定时器
if ( !(mmres=timeSetEvent(1, tc.wPeriodMin, OnSvrRecv, (DWORD)hSleep, TIME_PERIODIC)))
{
return 0;
} //接收缓冲区
WSABUF lpBuffers[1];
lpBuffers[0].buf = new char[RECV_ONE_PACKET];
lpBuffers[0].len = RECV_ONE_PACKET;
DWORD dwNumberOFBytesRecved = 0;
int nRet = 0;
DWORD dwFlag = 0; while (1)
{
int iExit = WaitForSingleObject(hExitEvent,0);
if(iExit==WAIT_OBJECT_0)
{
break;
} DWORD res = WaitForMultipleObjects(1,&hSleep,FALSE,INFINITE); //获取一包,得到头,用于判断是否获取完全
nRet = WSARecv(sServer_Connected, lpBuffers, 1, &dwNumberOFBytesRecved, &dwFlag, NULL, NULL);
if (nRet == 0 && pServerRecvBuffer != NULL && dwNumberOFBytesRecved > 0)
{
//获取实际数据长度
int iDataSize = *(int*)lpBuffers[0].buf;
//拷贝数据,去掉数据长度
memcpy(pServerRecvBuffer, lpBuffers[0].buf+sizeof(int), dwNumberOFBytesRecved-sizeof(int));
g_iServerRecvLen += dwNumberOFBytesRecved-sizeof(int); //再获取全部
while (g_iServerRecvLen < iDataSize)
{
nRet = WSARecv(sServer_Connected, lpBuffers, 1, &dwNumberOFBytesRecved, &dwFlag, NULL, NULL);
if(nRet == 0 && pServerRecvBuffer != NULL && dwNumberOFBytesRecved > 0)
{
memcpy(pServerRecvBuffer+g_iServerRecvLen, lpBuffers[0].buf, dwNumberOFBytesRecved);
g_iServerRecvLen += dwNumberOFBytesRecved; if(g_iServerRecvLen == iDataSize)
{
break;
}
}
else
{
// int nError = WSAGetLastError();
// wsprintf(msgBuf, "WSARecv failed, error:%d \n", nError);
// OutputDebugString(msgBuf);
}
} bSvrDataOK = TRUE;
}
}
timeKillEvent(mmres);
CloseHandle(hSleep);
hSleep = NULL;
delete []lpBuffers[0].buf;
lpBuffers[0].buf = NULL;
return 1;
}
{
TIMECAPS tc;
MMRESULT mmres;
if ( timeGetDevCaps(&tc,sizeof(tc))!=TIMERR_NOERROR )
{
FILE* fp = NULL;
fp = fopen(".\\TCP_CTEC.log","a+");
char info[INFO_SIZE];
memset(info, 0, INFO_SIZE);
sprintf(info, "%s\n", "Can't get client recv multimedia timer resolution");
fwrite(info,1,INFO_SIZE,fp);
fclose(fp);
fp = NULL;
return 0;
}
HANDLE hSleep = CreateEvent(NULL,FALSE,FALSE,NULL); if ( !(mmres=timeSetEvent(1, tc.wPeriodMin, OnSvrRecv, (DWORD)hSleep, TIME_PERIODIC)))
{
return 0;
} WSABUF lpBuffers[1];
lpBuffers[0].buf = new char[RECV_ONE_PACKET];
lpBuffers[0].len = RECV_ONE_PACKET;
DWORD dwNumberOFBytesRecved = 0; int nRet = 0;
DWORD dwFlag = 0; while (1)
{
int iExit = WaitForSingleObject(hExitEvent,0);
if(iExit==WAIT_OBJECT_0)
{
break;
} DWORD res = WaitForMultipleObjects(1,&hSleep,FALSE,INFINITE); //获取一包,得到头,用于判断是否获取完全
nRet = WSARecv(sClient, lpBuffers, 1, &dwNumberOFBytesRecved, &dwFlag, NULL, NULL);
if (nRet == 0 && pClientRecvBuffer != NULL &&dwNumberOFBytesRecved > 0)
{
int iDataSize = *(int*)lpBuffers[0].buf;
//拷贝数据
memcpy(pClientRecvBuffer, lpBuffers[0].buf+sizeof(int), dwNumberOFBytesRecved-sizeof(int));
g_iClientRecvLen += dwNumberOFBytesRecved-sizeof(int); //再获取全部
while (g_iClientRecvLen < iDataSize)
{
nRet = WSARecv(sClient, lpBuffers, 1, &dwNumberOFBytesRecved, &dwFlag, NULL, NULL);
if(nRet == 0 && pClientRecvBuffer != NULL &&dwNumberOFBytesRecved > 0)
{
memcpy(pClientRecvBuffer+g_iClientRecvLen, lpBuffers[0].buf, dwNumberOFBytesRecved);
g_iClientRecvLen += dwNumberOFBytesRecved;
if(g_iClientRecvLen == iDataSize)
{
break;
}
}
else
{
// int nError = WSAGetLastError();
// wsprintf(msgBuf, "WSARecv failed, error:%d \n", nError);
// OutputDebugString(msgBuf);
}
}
bClientDataOK = TRUE;
}
}
timeKillEvent(mmres);
CloseHandle(hSleep);
hSleep = NULL;
delete []lpBuffers[0].buf;
lpBuffers[0].buf = NULL;
return 1;
}extern "C" _declspec(dllexport) int InitServer(LPCSTR IPAddr, UINT SerPort)
{
/* The WinSock DLL is acceptable. Proceed. */
GROUP g = 0;
//
sServer = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_IP, NULL, g, 0);
//sServer = WSASocket(AF_INET, SOCK_RAW, IPPROTO_RAW, NULL, 0, WSA_FLAG_OVERLAPPED); //创建套接字
sockaddr_in sockAddr;
memset(&sockAddr, 0, sizeof(sockaddr_in));
sockAddr.sin_family = AF_INET;
sockAddr.sin_port = htons(SerPort);
sockAddr.sin_addr.S_un.S_addr = inet_addr(IPAddr);
int ret = bind(sServer, (sockaddr*)(&sockAddr), sizeof(sockaddr_in)); if (ret != 0)
{
return CTEC_BINDERR;
}
else
{
DWORD dwBytesReturned = 0;
BOOL bNewBehavior = TRUE; //ture 非阻塞 false 阻塞
DWORD status;
// disable new behavior using
// IOCTL: SIO_UDP_CONNRESET
status = WSAIoctl(sServer, FIONBIO,
&bNewBehavior, sizeof(bNewBehavior),
NULL, 0, &dwBytesReturned,
NULL, NULL); if (SOCKET_ERROR == status)
{
DWORD dwErr = WSAGetLastError();
if (WSAEWOULDBLOCK == dwErr)
{
// nothing to do
return 0;
}
else
{
return 0;
}
} int killnagle = 0;
int result = setsockopt(sServer, IPPROTO_IP, TCP_NODELAY, (const char*)&killnagle, sizeof(int)); if (result != 0)
{
return 0;
} setsockopt(sServer,SOL_SOCKET,SO_SNDBUF,(const char*)&nSendBuf,sizeof(int));
setsockopt(sServer,SOL_SOCKET,SO_RCVBUF,(const char*)&nRecvBuf,sizeof(int));
listen(sServer, 1);
ret = CTEC_SUCCESS; pServerRecvBuffer = new char[MAX_DATA_LEN];
memset(pServerRecvBuffer, 0, MAX_DATA_LEN); //起一个线程监听
DWORD dwAcceptThreadID = 0;
HANDLE hAcceptThread = CreateThread(NULL, 0, AcceptThread, 0, 0, &dwAcceptThreadID);
//起一个数据接收线程
DWORD dwRecvThreadID = 0;
HANDLE hRecvThread = CreateThread(NULL, 0, SvrRecvThread, 0, 0, &dwRecvThreadID);
if(!SetThreadPriority(hRecvThread, THREAD_PRIORITY_TIME_CRITICAL))
{
FILE* fp = NULL;
fp = fopen(".\\TCP_CTEC.log","a+");
char info[INFO_SIZE];
memset(info, 0, INFO_SIZE);
sprintf(info, "%s\n", "Set the SVR recv thread failed!");
fwrite(info,1,INFO_SIZE,fp);
fclose(fp);
fp = NULL;
return 0;
}
return sServer;
}
}
extern "C" _declspec(dllexport) int RecvData(char * RevData, int DataLen,UINT uSocket)
{
int ret = 0; if (uSocket == sServer)
{
if (DataLen >= g_iServerRecvLen)
{
if (g_iServerRecvLen > 0 && bSvrDataOK)
{
memcpy(RevData, pServerRecvBuffer, g_iServerRecvLen);
ret = g_iServerRecvLen;
g_iServerRecvLen = 0;
bSvrDataOK = FALSE;
}
else
ret = CTEC_TIMEOUT;
}
else
ret = CTEC_SOCKETERR_GETDATALEN;
}
else if (uSocket == sClient)
{
if (DataLen >= g_iClientRecvLen)
{
if (g_iClientRecvLen > 0 && bClientDataOK)
{
memcpy(RevData, pClientRecvBuffer, g_iClientRecvLen);
ret = g_iClientRecvLen;
g_iClientRecvLen = 0;
bClientDataOK = FALSE;
}
else
ret = CTEC_TIMEOUT;
}
else
ret = CTEC_SOCKETERR_GETDATALEN;
}
else
ret = CTEC_SOCKETERR; return ret;
}
extern "C" _declspec(dllexport) int Exit_Server(UINT uSocket)
{
if (hExitEvent != NULL)
{
SetEvent(hExitEvent);
//等待处理结束
Sleep(1000);
CloseHandle(hExitEvent);
hExitEvent = NULL;
} delete []pServerRecvBuffer;
pServerRecvBuffer = NULL;
if (sServer_Connected != INVALID_SOCKET)
closesocket(sServer_Connected);
if (sServer != INVALID_SOCKET)
closesocket(sServer);
return 0;
}
extern "C" _declspec(dllexport) int InitClient(LPCSTR sServerAddr, UINT uSerPort)
{
GROUP g = 0;
// sClient = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, g, 0);
sClient = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_IP, NULL, g, 0); sockaddr_in dstAddr;
dstAddr.sin_family = AF_INET;
dstAddr.sin_addr.S_un.S_addr = inet_addr(sServerAddr);
dstAddr.sin_port = htons(uSerPort); int ret = WSAConnect(sClient, (sockaddr*)(&dstAddr), sizeof(SOCKADDR), NULL, NULL,NULL, NULL ); if (ret == 0)
{
pClientRecvBuffer = new char[MAX_DATA_LEN];
memset(pClientRecvBuffer, 0, MAX_DATA_LEN);
DWORD dwBytesReturned = 0;
BOOL bNewBehavior = TRUE; //ture Not blocking false blocking
DWORD status;
// disable new behavior using
// IOCTL: SIO_UDP_CONNRESET
status = WSAIoctl(sClient, FIONBIO,
&bNewBehavior, sizeof(bNewBehavior),
NULL, 0, &dwBytesReturned,
NULL, NULL); if (SOCKET_ERROR == status)
{
DWORD dwErr = WSAGetLastError();
if (WSAEWOULDBLOCK == dwErr)
{
// nothing to do
return 0;
}
else
{
return 0;
}
} int killnagle = 0;
int result = setsockopt(sClient, IPPROTO_IP, TCP_NODELAY, (const char*)&killnagle, sizeof(int)); if (result != 0)
{
return 0;
} setsockopt(sClient,SOL_SOCKET,SO_SNDBUF,(const char*)&nSendBuf,sizeof(int));
setsockopt(sClient,SOL_SOCKET,SO_RCVBUF,(const char*)&nRecvBuf,sizeof(int)); /*for test
DWORD dwNumberOFBytesSent = 0;
WSABUF lpBuffers[1];
//长度需要加个头,表示长度
lpBuffers[0].buf = new char[MAX_DATA_LEN];
memset(lpBuffers[0].buf, 0, MAX_DATA_LEN);
*(int*)(lpBuffers[0].buf) = MAX_DATA_LEN - sizeof(int);
lpBuffers[0].len = MAX_DATA_LEN;
ret = WSASend(sClient, lpBuffers, 1, &dwNumberOFBytesSent, 0, NULL, NULL );
*/
//起一个数据接收线程
DWORD dwRecvThreadID = 0;
HANDLE hRecvThread = CreateThread(NULL, 0, ClientRecvThread, 0, 0, &dwRecvThreadID);
if(!SetThreadPriority(hRecvThread, THREAD_PRIORITY_TIME_CRITICAL))
{
FILE* fp = NULL;
fp = fopen(".\\TCP_CTEC.log","a+");
char info[INFO_SIZE];
memset(info, 0, INFO_SIZE);
sprintf(info, "%s\n", "Set the Client recv thread failed!");
fwrite(info,1,INFO_SIZE,fp);
fclose(fp);
fp = NULL;
return 0;
}
return sClient;
}
else
return CTEC_CONNECTTIONERR;}
extern "C" _declspec(dllexport) int SendData(char * cData, int iDataLen ,int *uSocket)
{
WSABUF lpBuffers[1];
//长度需要加个头,表示长度
lpBuffers[0].buf = new char[iDataLen+sizeof(int)];
lpBuffers[0].len = iDataLen + sizeof(int); //将数据长度放在头4个字节
memcpy(lpBuffers[0].buf, &iDataLen, sizeof(int));
//拷真正的数据
memcpy(lpBuffers[0].buf+sizeof(int), cData, iDataLen); DWORD dwNumberOFBytesSent = 0; int ret = 0;
if (*uSocket == sClient)
{
ret = WSASend(sClient, lpBuffers, 1, &dwNumberOFBytesSent, 0, NULL, NULL );
}
else if (*uSocket == sServer)
{
ret = WSASend(sServer_Connected, lpBuffers, 1, &dwNumberOFBytesSent, 0, NULL, NULL );
} if (dwNumberOFBytesSent != iDataLen + sizeof(int))
ret = CTEC_TIMEOUT; delete []lpBuffers[0].buf;
lpBuffers[0].buf = NULL;
return ret;
}
extern "C" _declspec(dllexport) int Exit_Client(UINT uSocket)
{
if (hExitEvent != NULL)
{
SetEvent(hExitEvent);
//等待处理结束
Sleep(1000);
CloseHandle(hExitEvent);
hExitEvent = NULL;
} delete []pClientRecvBuffer;
pClientRecvBuffer = NULL;
if(sClient != INVALID_SOCKET)
closesocket(sClient);
return 0;
}
不扑空才怪!
都不要看代码都可知楼主的问题了,帖那长代码干嘛?
也就是说,客户端发给服务器端,服务端40MS后反馈给客户端。
问题是客户端有时候要超过100MS后才能收到。不正常。