我用socket编写一个网络程序,用的是TCP/IP 协议,我认为socket发送的内容应该是安全的但是。
socket接受到的数据确是有乱码的。有时还接受不到。。这是为什么?
有什么解决的办法么?
以下是我写的一段代码。
int iSign = 3;
char * pSend = (char *)&iSign;
send(pMain->m_socketContent,pSend,sizeof(int),0);
iSign = 7;
send(pMain->m_socketContent,pSend,sizeof(int),0);
int retval = recv(sock,q,sizeof(int),0);;
if (iSign == 1)
{
int a;
char * data = (char *)&a;
UINT dw2 =recv(sock,data,sizeof(int),0);
        dw2 =recv(sock,data,sizeof(int),0);
                }...........

解决方案 »

  1.   

    注意处理send和recv的返回值,这才是实际send/recv的字节数。
      

  2.   

    “注意处理send和recv的返回值,这才是实际send/recv的字节数。”
    这个我知道,现在程序能够接受到东西但是有时 char a = -52
    是乱码,那我的数据到哪去了???????我不太明白
      

  3.   

    我测试过,,返回值都是对的但是iSign = -52 或者 char的数组就是一堆乱码
      

  4.   

    首先判断发送和接收是否成功,如果返回值是SOCKET_ERROR就说明失败了,用WSAGetLastError取一下错误码看一下是什么错误。
    你该不会是没建立连接吧?
      

  5.   

    char szBuff[5];
    memset(szBuffer,0,5);
    UINT n = recv(sock,szBuffer,sizeof(int),0);
    int nResult = atoi(szBuffer);
    试下 .
      

  6.   

    bool Send(SOCKET s,const char * Buf,const int Length)
    {
      int SendRet,NeedSend = Length;
      char *sending = Buf;
      while(NeedSend){
        SendRet = send(s,sending,NeedSend,0);
        if (SendRet==SOCKET_ERROR) return false;//发送失败
        if (!SendRet)return false;//连接断开
         NeedSend -= SendRet;
        sending += SendRet;
      }
      return true;//发送成功
    }
      

  7.   


    int   retval   =   recv(sock,q,sizeof(int),0);;
    if   (iSign   ==   1)
    {
    int   a;
    char   *   data   =   (char   *)&a;
    UINT   dw2   =recv(sock,data,sizeof(int),0);
                    dw2   =recv(sock,data,sizeof(int),0);
                                    }
    //////////////////
    我个人认为,接受数据有问题. 控制语句应该是多余的. 你可以一次全部接受完收据,也可以像你上面的只接受int长度的,但你发几个长度就接受多少长度的. 详细说明你要实现的功能.
      

  8.   

    已经连接了。。if       (iSign       ==       1) 

    }这个只是当中的一部分;
    iSign代表的是不同的命令代号,根据不同的iSign再接受不同的数据
      

  9.   

    程序接受方面没有问题,也没出现Error;但是接受的数据内容不太对
      

  10.   

    而对于recv,更需要处理它的长度。也许你习惯性使用的是固定数组(这里只是说也许),对于固定数组在得到返回值之后需要很好的处理实际收到的数据字节数,而不是整个数组,否则你的数组有1024字节,就全当数据,那就有可能会多了很多非数据的“数据”。初始化(通常情况下是清零)并不是完全必要的,那只是为了调试时阅读的方便。即便是可靠的字符串传输当中,那也仅仅只需要将末位清为'\0',而完全没有浪费时间去将整个Buffer清空。
      

  11.   

    1.先研究一下网络字节顺序和主机字节顺序。
    2.发数据前,把int型数据用htonl()函数转换后存入char数组,然后发送。
    3.收到数据后,把收到的char数组前4个字节用ntohl()函数转换后复制给int型变量。
      

  12.   

    比如说:
    我传送一个名字char数组类型的,先传这个数组的长度,再根据长度传数组。但有时收到的就是一堆乱码这是为什么?
      

  13.   

    同样的接收也是分步骤的。你不能假定想接收的数据长度较小,比如几十个字节就一定能一性次接收完成,这是不对的。只要接收没有超时或者出错,那么在最坏的情况下很有可能只有一个字节(当然,这几乎是不可能发生的,但是这只是一个问题的说明,虽然极不可能是一个字节,但是四个五个字节呢?几十个字节呢?)。对于定长的数据。bool Recv(SOCKET s, const char *Buf, const int NeedRecv,int   &RecvLength) 

      int RecvRet, iNeedRecv = NeedRecv; 
      char   *recving = Buf; 
      RecvLength = 0;
      while(iNeedRecv){ 
        RecvRet = recv(s, recving, iNeedRecv, 0); 
        if(RecvRet == SOCKET_ERROR)
          return false;//发送失败 
         if(!RecvRet)
          return false;//连接断开 
         iNeedRecv -= RecvRet;
        RecvLength += RecvRet;
        recving += RecvRet; 
      } 
      return true;//发送成功 
    }
      

  14.   

    1.先研究一下网络字节顺序和主机字节顺序。 
    2.发数据前,把int型数据用htonl()函数转换后存入char数组,然后发送。 
    3.收到数据后,把收到的char数组前4个字节用ntohl()函数转换后复制给int型变量。 
    ===============
    网络字节序与主机字节序的问题,在应用协议层,只与接收和发送两端的主机系统有关系,从楼主贴的代码以及后面的文字看,问题并不在这里。
      

  15.   

    那可不可以把socket的缓冲区的内容清除呢??怎么做?我查了一下其他的帖子,有人说可以Sleep()一段时间,还有没有其他的方法???谢谢大家!!
      

  16.   

    因为长度保存在int型变量里面,是4个字节长,
    比如0x12345678。如果不做字符顺序转换处理,
    你收到后会变成0x78563412。
      

  17.   

    楼主发送数据的代码里,int型数据直接按char数组发,这样不行。
      

  18.   

    如果要把长度告诉对方,代码如下:
    1.发送方:
    unsigned int iSign   =   htonl(3); 
    char   *   pSend   =   (char   *)&iSign; 
    send(pMain-> m_socketContent,pSend,sizeof(int),0); 2.接收方:
    unsigned int bufLen;
    int   retval   =   recv(sock,bufLen,sizeof(unsigned int),0);
    bufLen = ntohl(bufLen);
      

  19.   

    把# unsigned的修改了一下, int  Recv(SOCKET s, const char *Buf, const int NeedRecv,int   &RecvLength) 

      int nRecvRet; 
      char   *cRecving = Buf; 
      int iRcvData[MAXLEN] = {0};
      nRecvRet = recv(s, cRecving , MAXLEN, 0);  //长度比如为1024
      if(nRecvRet == SOCKET_ERROR)
      {
         MessageBox("接受错误");
         return 0;
      }
      if(!nRecvRet)
      {
         MessageBox("连接中断");
         return 0;
      }  iRcvData = (int *)cRcving; 
      return iRcvData[NeedRecv];//接受成功 
    }
      

  20.   

    我想说的是:我的程序是可以正常运行的,但是在随机的情况下会崩溃,我查下来是:socket是收到数据的,但Socket收到的数据不正确,比如出现乱码,,或者int类型的数据收到如-82303113这类的一看就知道是错误的信息,,,,我找不到原因,,,,,请问有谁知道?????
      

  21.   

    你把htonl(), ntohl()两个函数整明白没?
    你发送数组长度的代码不对。
      

  22.   

    WORD wRawData = 3;BYTE byHigh, byLow;
    byHigh= HIBYTE(wRawData);
    byLow= LOBYTE(wRawData);char   *   pSend;pSend[0] = byHigh;
    pSend[1] = byLow;
    send(pMain-> m_socketContent,pSend,sizeof(int),0);
    iSign   =   7;
    send(pMain-> m_socketContent,pSend,sizeof(int),0); 
    if   (iSign   ==   1)
    {
    int   a;
    char   *   data;
    UINT   dw2   =recv(sock,data,2,0);WORD wRawData = MAKEWORD(data[1], data[0]);        
      

  23.   

    “你把htonl(),   ntohl()两个函数整明白没? 
    你发送数组长度的代码不对。”
    char   *   data   =   (char   *)&a; 
    不可以这样强制类型转换么?而且,如果这个出错的话,那应该是程序全部不行,但为什么我的程序有时正常,有时不正常呢?
      

  24.   

    unsigned的意见楼主也要核实一下,
    比如你的发送方,先调用send发了一个1字节数据,
    再调用send发一个4字节数据,
    再调用send发一个500字节数据。
    你的接受方调用recv收到的数据有多少,是不是把上面
    3部分数据都收下来了,
    怎么分割成你想要的3部分,需要你自己在代码里控制的。
      

  25.   

    上面代码实现的是单个int类型的发送接受 . 发送多个类似, 只要在接受时找好你所要的高低位数据然后转换成 int类型.
      

  26.   

    发送的时候是sizeof(int)
    接收的时候是char*类型,要sizeof(int)+1
      

  27.   

    int   retval   =   recv(sock,q,sizeof(int),0);; 
    if   (iSign   ==   1) 

    int   a; 
    char   *   data   =   (char   *)&a; 
    UINT   dw2   =recv(sock,data,sizeof(int),0); 
                    dw2   =recv(sock,data,sizeof(int),0); 
                                    } ...........我想象的可能性:你并没有把保证发送的数据被全部正确接收。同一个连接里,你正常逻辑需要send了100,同时recv到100,但可能recv到60的时候程序出错,后续recv40的代码没有被执行,则剩余的40被留在下次recv时接收到,因此影响了下次的正常数据。