我做了个简单的 TCP程序,但发现丢包很严重,代码如下:用Client端发送数据,
两个包之间如何Sleep()小于300ms都会丢包(在两台pc运行是这样,如何在同一台pc,sleep() 50ms就不会丢包了),为什么会这样????Server端代码:
int err;
WSADATA wsaData; if(WSAStartup(0x202, &wsaData) != 0)
{
m_pLog->Print("ERROR! Socket init fail!\n");
return ;
} SOCKET m_sServerSocket = socket( AF_INET, SOCK_STREAM, IPPROTO_IP );
    if( m_sServerSocket == SOCKET_ERROR )
    {
        err = WSAGetLastError();
m_pLog->Print("ERROR! Server socket create error:%d\n", err );
        return ;
    } sockaddr_in local; local.sin_addr.s_addr = htonl( INADDR_ANY );
    local.sin_family = AF_INET;
    local.sin_port = htons( 4567 ); if( bind(m_sServerSocket, (struct sockaddr *)&local, sizeof(local)) == SOCKET_ERROR )
    {
err = WSAGetLastError();
m_pLog->Print("ERROR! Server socket bind error:%d\n", err );
closesocket( m_sServerSocket );
        return ;
    }    if( listen(m_sServerSocket, 5) != 0)
{

err = WSAGetLastError();
m_pLog->Print("ERROR! Server socket listen error:%d\n",err);
closesocket( m_sServerSocket );
        return ;
    }

int iAddrSize;
struct sockaddr_in addr;

iAddrSize = sizeof(addr); SOCKET sClient = accept( m_sServerSocket, (struct sockaddr *)&addr, &iAddrSize); int iRet;
char buffer[512];
teststru* pStru; m_oSvrOpen.EnableWindow( false ); 
while(1)
{
memset( buffer, 0, sizeof(buffer));
iRet = recv( sClient, buffer, sizeof(buffer), 0 ); if(iRet <= 0)
{
Sleep( 10 );
continue;
} pStru  = (struct teststru*)buffer; m_pLog->Print("rev sequence = %d \n", pStru->iSeq ); }----------------------------------------------------------
Client 代码
WSADATA wsaData;
if( WSAStartup(0x202, &wsaData) != 0 )
{
m_pLog->Print("ERROR! Initialize fail: socket init fail!\n");
return ;
} LPHOSTENT lpHost;
struct sockaddr_in server;
SOCKET sSocket;
char ipaddr[20];
memset(ipaddr, 0, sizeof(ipaddr)); if(m_oIpAddr.GetWindowTextLength() <= 0 )
return; m_oIpAddr.GetWindowText(ipaddr, m_oIpAddr.GetWindowTextLength() + 1 );   lpHost = gethostbyname(ipaddr);
if(lpHost == NULL) return;

server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr(ipaddr);
server.sin_port=htons(4567);

sSocket = socket(AF_INET, SOCK_STREAM, 0);

if(sSocket <= 0)
{
//err = WSAGetLastError();
Sleep(30);
return;
}

if(connect(sSocket, (LPSOCKADDR)&server, sizeof(SOCKADDR)) != 0 )
{
// err = WSAGetLastError();
shutdown(sSocket,2);
closesocket(sSocket);
Sleep(300);
return;
} m_oClientOpen.EnableWindow( false ); 
teststru oStru;
int iRet;
for(int i = 0; i < 1000; i++)
{
oStru.iSeq = i;
iRet = send( sSocket, (char *)&oStru, sizeof(struct teststru), 0); if(iRet <= 0)
{
Sleep(100);
continue;
} m_pLog->Print("send sequence = %d \n", i ); 
Sleep( 100 );
}
}

解决方案 »

  1.   

    你应该找找你程序中将数据传到发送部份,tcp是不会丢包的。
      

  2.   

    不是丢包,是你接收方式不对,有可能一次接收到多个或部分struct teststru的结构,第二次就把先前的接收的部分丢掉了。 memset( buffer, 0, sizeof(buffer));
    iRet = recv( sClient, buffer, sizeof(buffer), 0 );
    改为
                      // buffer 要大于等于1 个teststru
    memset( buffer, 0, sizeof(buffer)); 
                      // 一次接收一个 teststru
    iRet = recv( sClient, buffer, sizeof(teststru), 0 );
      

  3.   

    同意楼上:你发的少收的多,发一个收十个,用pStru  = (struct teststru*)buffer;赋值时只有一个有效
      

  4.   

    多谢w3guy(Jaz), 确实是接收方式不对,按你的方法处理ok了
      

  5.   

    是的不是丢包!tcp还丢包就不可靠了.