TCP/IP通讯问题

CappuccinoHu 2009-12-10 10:53:24
我用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));
...全文
202 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
CappuccinoHu 2009-12-11
  • 打赏
  • 举报
回复
不怎么会扑空呢?
也就是说,客户端发给服务器端,服务端40MS后反馈给客户端。
问题是客户端有时候要超过100MS后才能收到。不正常。

CappuccinoHu 2009-12-10
  • 打赏
  • 举报
回复
DWORD WINAPI ClientRecvThread(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 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;
}
CappuccinoHu 2009-12-10
  • 打赏
  • 举报
回复
所有代码:

#include "stdafx.h"


#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;
}

ccpaishi 2009-12-10
  • 打赏
  • 举报
回复
楼主把客户端的发送和接受部分全部单独写到一个线程里面试试看。楼主代码没有完全贴出来,我也不敢下结论。
一般来说,长时间之后出现丢包和延时的现象我的经验都是因为放在主线程里面做导致的。
CappuccinoHu 2009-12-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));

根本就通不起来,发送和接收都非常缓慢。

bragi523 2009-12-10
  • 打赏
  • 举报
回复
以你的发送频率来说
可以把发送缓冲区设空
CappuccinoHu 2009-12-10
  • 打赏
  • 举报
回复
100M局域网,可以说没有其他干扰。
就两台电脑,1个HUB,相连。

数据量在100K左右。

10分钟的规律最疑惑了,用UDP也是这种效果,10分钟必丢一包。
Wenxy1 2009-12-10
  • 打赏
  • 举报
回复
你发的数据量大么,网络环境好吗?
数据接收和发送有一定的延迟是正常的。
awjx 2009-12-10
  • 打赏
  • 举报
回复
一个40ms,一个100ms,这样等?
不扑空才怪!
都不要看代码都可知楼主的问题了,帖那长代码干嘛?

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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