客户端主要代码如下://用户信息的结构
typedef struct
{
long id;
char nickname[20];
char sex[10];
int age;
char address[50];
char password[20];
}USER_INF,*LPUSER_INF;        SOCKET sClient;
SOCKADDR_IN inetAddr;
USER_INF userInf;sClient=socket(AF_INET, SOCK_STREAM, 0); inetAddr.sin_addr.s_addr=inet_addr("127.0.0.1");  //联接本机的IP
inetAddr.sin_family=AF_INET;
inetAddr.sin_port=htons(SERVER_PORT); if(connect( sClient, (struct sockaddr *)&inetAddr, sizeof (inetAddr)) == SOCKET_ERROR) 
{
AfxMessageBox("注册失败:不能连接Net服务器");
return ;
}
        UpdateData(TRUE); m_cbSex.GetLBText(m_cbSex.GetCurSel(), m_strSex); if(m_strPwd != m_strVerifyPwd)
{
AfxMessageBox("密码与确认密码不一致");
return ;
}
if(m_strNickname == _T("") || m_nAge==0 || m_strAddress==_T(""))
{
AfxMessageBox("请填充所有选项");
return ;
}

memset(&userInf,0,sizeof(USER_INF));
userInf.id = 0;
strcpy(userInf.nickname, (LPCTSTR)m_strNickname);
strcpy(userInf.sex, (LPCTSTR)m_strSex);
userInf.age = m_nAge;
strcpy(userInf.address, (LPCTSTR)m_strAddress);
strcpy(userInf.password, (LPCTSTR)m_strPwd); //send "REGT"信息
memset(buff,0,sizeof(buff));
sprintf(buff,"%s","REGT"); if(send(sClient,buff,sizeof(buff),0) == SOCKET_ERROR)
{
AfxMessageBox("注册失败:REGT 信息 send 出错");
        closesocket(sClient);
return ;
}        //send userInf
if(send(sClient,(char *)&userInf,sizeof(USER_INF),0) == SOCKET_ERROR) //USER_INF userInf已被赋值
{
AfxMessageBox("注册失败:REGT userInf send 出错");
        closesocket (sClient);
return ;
}服务端主要代码如下://保存在线用户的结构
typedef struct
{ char ip[16]; //用户的IP地址
SOCKET sock;
UINT currentnumer; //当前用户排第几位}ONLINEUSER_INF,*LPONLINEUSER_INF;        ONLINEUSER_INF  userinfo;        USER_INF  inf;        recv(userinfo.sock ,str,10,0);  //userinfo.sock 为客户端的SOCKET
        CString string;
        string.Format ("%s",str);        if(string==_T("REGT"))
        {             memset(&inf,0,sizeof(USER_INF));
 if(recv(userinfo.sock,(char *)&inf,sizeof(USER_INF),0)== SOCKET_ERROR)
 {
 closesocket(userinfo.sock);
     AfxMessageBox("REGT recv命令出错");
     return 1;
 }
        }编译无错误显示,但是服务器接收的USER_INF结构信息为空,怎么回事啊???请大哥们指教,谢谢!!!顶者有分!!!!

解决方案 »

  1.   

    这估计是TCP粘包的原因吧,像这样的数据用UDP协议就行了!
      

  2.   

    ret =send(sClient,(char *)&userInf,sizeof(USER_INF),0)
    if(ret == SOCKET_ERROR || ret == 0)
    {
    AfxMessageBox("注册失败:REGT userInf send 出错");
    closesocket (sClient);
    return ;
    }
    这样看看
      

  3.   

    你看看是不是你的UpdateData 用错误了
      

  4.   


    TO:shubing820904 大哥UpdateData() 没用错,客户端发送userInf结构时,userInf已被赋值//////////////////////////////////////////////////////////////////////TO:mynamelj(风之羽翼) 大哥如果是TCP粘包的原因,用TCP协议该怎么改??
      

  5.   


    TO:mynamelj(风之羽翼) 大哥我的程序中客户端和服务器都在同一个机子(我打算先试验一下),应该不会有 TCP粘包 现象吧
      

  6.   

    最好是用UDP协议,TCP为了改善性能问题肯定是会粘包的。
      

  7.   


    TO:mynamelj(风之羽翼) 大哥我知道最好是用UDP协议,问题是我必须用TCP协议(作业设定),应该怎样避免TCP粘包现象??
    代码应该怎样修改?? 请指教!!!PS:客户端和服务器都在同一个机子,也会有 TCP粘包 现象吗??
    在我看来,没经过网线传输导致延迟,只在同一个机子里输送和接受,应该不会吧 
      

  8.   

    你每次發的包大小不等,不然的話你可以設置send buffer大小來改善。這樣好了,你定義一個固定尺寸的buffer,發之前將數據memcpy到這個buffer裏去,然後將這個buffer發出去。
      

  9.   

    跟不跟就无所谓了,你要知道是不是粘包你判断一下recv收到了多少数据就行了
      

  10.   


    TO: mynamelj(风之羽翼) 兄
    .............可以設置send buffer大小來改善................
    我应该设定多大的buffer才合适???PS: 我用TCP协议,应该怎样避免TCP粘包现象?? 我原来的代码应该怎样修改?? 谢谢mynamelj(风之羽翼) 兄的指点,希望你能给我正确的方法,我还是太菜,再次感谢^_^
      

  11.   

    http://hi.baidu.com/liuwenfei54/blog/item/24fe282dc1f7de34359bf7e1.html
      

  12.   

    你看一下是不是你在Send是设置buff长度时出的问题,你将send中buff长度参数比实际数据长度加一看看!
      

  13.   

    问题处在你接收的地方,
    recv(userinfo.sock ,str,10,0);  //userinfo.sock 为客户端的SOCKET
    这里接收了长度为10,但是你的发送的数据第一部分是4啊“REGT"(不考虑unicode情况)
    这样你第二次接收数据的时候,就是接收不全需要的结构体,当然会出错了。
    解决的办法是:发送多少接收多少,最好使用模型
      

  14.   

    最土的方法就是
    recv(userinfo.sock ,str,10,0);  
    改成
    recv(userinfo.sock ,str,strlen(”regt“),0);  
      

  15.   

    改成固定长度的buffer块传送并接受
      

  16.   


    谢谢楼上各位大哥的指点,我回家后试试TO: ddddfbb(ddd_ddd1) 兄
    我看不出 sizeof(buff) 那里错了,请你讲明白好吗
      

  17.   

    你看下程序会不会执行  memset(&inf,0,sizeof(USER_INF));
     if(recv(userinfo.sock,(char *)&inf,sizeof(USER_INF),0)== SOCKET_ERROR)
     {
     closesocket(userinfo.sock);
         AfxMessageBox("REGT recv命令出错");
         return 1;
     }
    这些代马
      

  18.   

    看不到你Client端buff的定义,不过大致已经看明白问题的原因了
    memset(buff,0,sizeof(buff));
    sprintf(buff,"%s","REGT");
    这两行是把buff置数据的吧?
    运行以后buff的内容应该是"REGT\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0......"
    buff中除了REGT的部分应该全部是\0ok,看下面:
    if(send(sClient,buff,sizeof(buff),0) == SOCKET_ERROR)
    这行表示你把buff传送出去
    你认为它应该只发了"REGT"是吗?那么你错了
    发送的数据有多少取决于buff你定义了多大
    如果是buff[1024],那么恭喜你,你这次传输一共发出去了1024字节,因为sizeof(buff)=1024下面继续看你的Server端:
            recv(userinfo.sock ,str,10,0);  //userinfo.sock 为客户端的SOCKET
            CString string;
            string.Format ("%s",str);
    首先收了10个字节,这10个字节应该是发送的数据的"REGT\0\0\0\0\0\0\0\0\0\0\0\0......"前10个字节
    也就是收到了"REGT\0\0\0\0\0\0"
    接下来string处理没错,以上应该相等于"REGT\0"关键地方到了
    你接着收USER_INF,
    if(recv(userinfo.sock,(char *)&inf,sizeof(USER_INF),0)== SOCKET_ERROR)
    这句拿到的是什么?
    你以为它应该收Client发送的USER_INF对吗?
    那么你错了,它收的其实是上次buff中除了前10个字节以外的剩余部分
    也就是说如果buff大小是1024,那么socket中还有1014个字节的'\0'在等着你呢在这种情况下,USER_INF中全部是0就不奇怪了,因为数据本身就都是0,呵呵这么解释明白了吗?弄明白了要记着结贴给分哦 -0-
    -------------------------------------------------------
    广告:VC/WinAPI 网络/多线程讨论 QQ群, 群号:41356711
      

  19.   

    楼主an_941与8楼的an_94啥关系,,从实招来,,
      

  20.   


    楼主an_941与8楼的an_94啥关系,,从实招来----------------------------------------哈哈哈,一时兴起,注册了两个帐号而已^_^
      

  21.   

    UPUPUPUPUP..............
      

  22.   

    TO  fantiyu 兄:不好意思,问题解决了,不过我不知道怎么给分,请老兄教我,谢谢了^_^PS:我保证把大部分的分给老兄你,希望大哥继续关照小弟^_^
      

  23.   


    UPUPUPUPUPUP....................
      

  24.   

    发送端send的len应该和接收端recv的len 一样才行!
      

  25.   

    严重支持楼主!http://topic.csdn.net/u/20080110/19/7cb462f1-cac6-4c28-848e-0a879f4fd642.html