UDP的长度限制应该在8k左右。查一下你的目的机器程序吧

解决方案 »

  1.   

    你说的不是太清楚,但我想是这样的:
    len是数据长度,你改变了len的值,当send和len不匹配,你就应该发送其他的数据。所以你什么也没接收到。
      

  2.   

    我用的是CSocket派生类,没做什么改动,只是将OnReceive改了一下处理函数【多了一个调用函数而已】void CMySocket::OnReceive(int nErrorCode) 
    {    pParent->OnGetMessage();// pParent为我的一个类,里面有一个OnGetMessage处理函数

        CSocket::OnReceive(nErrorCode);
    }
      

  3.   

    udp采用的是无连接传输协议的,所以在传送的过程中不能保证能不能成功,你试试在代码中
    循环发送SendTo看看行不行
      

  4.   

    udp的长度确实是在8K左右.
    强制也不行.
      

  5.   

    SendTo应该是成功的,那多半是接收有问题。比如接收的Buffer你可能只开了100或者200字节。
      

  6.   

    那CSocket的默认Buffer是多少?如果太少,该如何设定他的大小呢?
      

  7.   

    主  题: <&brvbar;&brvbar;&brvbar;&brvbar;&brvbar;&brvbar;&brvbar;&brvbar;&brvbar;&brvbar;&brvbar;&brvbar;&brvbar;&brvbar;&brvbar;&brvbar;&brvbar;\-  winsock2问题  -/&brvbar;&brvbar;&brvbar;&brvbar;&brvbar;&brvbar;&brvbar;&brvbar;&brvbar;&brvbar;&brvbar;&brvbar;&brvbar;&brvbar;&brvbar;&brvbar;&brvbar;&brvbar;&brvbar;>
    作  者:cathy0505
    所属论坛:Visual C++
    问题点数:300
    回复次数:36
    人气指数:838
    发表时间:2001-6-27 8:36:14
     
    //无关内容略if(sendto(s, buffer, sizeof(buffer), 0, (SOCKADDR *)&remote, sizeof(remote)) == SOCKET_ERROR)
        
        
              printf("failed %d",WSAGetLastError());
    结果输出    failed 10040
    请问,这里sendto错误的10040是什么?
    怎么引起的?怎么处理?? 
    回复贴子: 
     SuperProgMan(编程者) 回复于2001-6-27 8:40:16 得30分  
    一个在数据报套接字上发送的消息大于内部消息缓冲器或其它一些网络限制,或该用户用于接收数据报的缓冲器比数据报小。buffer是不是太大了?  
     runbuff(玩火人) 回复于2001-6-27 8:40:41 得30分  好几天不见了,你好啊。你用的是UDP吗?
     
     XiangDong(木头) 回复于2001-6-27 8:41:18 得30分  
    A message sent on a datagram socket was larger than the internal message buffer or some other network limit, or the buffer used to receive a datagram into was smaller than the datagram itself. 
                              From MSDN, Win32 Error Codes  
     seesi(不是我想骗你,是我不知道怎么才能不骗!) 回复于2001-6-27 8:43:50 得30分  
    发送数据过大?  
     seedundersnow() 回复于2001-6-27 8:44:28 得30分  或许,可以考虑用 FormatMessage() 试试?
    用法我不太清楚,自己看msdn吧 
     cathy0505() 回复于2001-6-27 8:56:43 得0分  
    sendto的buffer是65535那么大(string的极限)原来buffer过大引起10040错误,那么buffer应该是多大呢?为什么send函数同样发送这个buffer没有出现此错误呢?sendto的buffer最大是多少?  
     Kevin_qing() 回复于2001-6-27 9:03:43 得30分  
    sendto在局域网里面16K-32K左右差不多;
    如果是拨号的话,1K-2K  
     xxxbird(*说你行,你就行,不行也行*) 回复于2001-6-27 9:08:40 得30分  
    You can use getsockopt to retrieve the maximum packet size of socket with option SO_MAX_MSG_SIZE.getsockopt (s, SOL_SOCKET, SO_MAX_MSG_SIZE, ...);
     
     cathy0505() 回复于2001-6-27 9:11:22 得0分  
    to Kevin_qing(Kevin):
        这里的buffer跟接收端没有多大关系吧,
        你指的是本机的buffer么?我用的是100Mb出口的服务器,发送64K应该没多大问题吧。
     
     xxxbird(*说你行,你就行,不行也行*) 回复于2001-6-27 9:22:38 得30分  
    通常send函数主要应用于TCP协议的数据传输,TCP本身有自己的缓冲区,send函数结束之后并不表明数据已经传到了目标机器,只是从应用程序拷贝到TCP协议栈的缓冲区罢了。sendto函数有所不同,它主要应用于UDP协议的数据传输,而UDP协议本身是没有缓冲区的。如果传送的数据长度超过maximum packet size, 它就会出现上述的错误。通常一个TCP socket的MPS(maximum packet size) 大于 UDP socket的 MPS。  
     xxxbird(*说你行,你就行,不行也行*) 回复于2001-6-27 9:23:48 得30分  
    你可以用创建一个TCP socket和一个UDP socket 试试看。  
     cathy0505() 回复于2001-6-27 9:25:22 得0分  
    TO xxxbird(*说你行,你就行,不行也行*) 
            请告诉我getsockopt (s, SOL_SOCKET, SO_MAX_MSG_SIZE, ...);最后两个参数怎么写。我看见第4个参数型为char FAR*  ,那么char*怎么指定msg的size呢?  
     Sunny_lin(大和尚) 回复于2001-6-27 9:29:19 得0分  
    WSAEMSGSIZE 
    (10040) 
    Message too long. 
    A message sent on a datagram socket was larger than the internal message buffer or some other network limit, or the buffer used to receive a datagram into was smaller than the datagram itself. 
     
     Kevin_qing() 回复于2001-6-27 9:30:52 得30分  
    我指的是每次send的size,超过这个size丟包会很严重的  
     Kevin_qing() 回复于2001-6-27 9:32:40 得0分  int size;
    getsockopt (s, SOL_SOCKET, SO_MAX_MSG_SIZE, (LPSTR)&size,sizeof(int));
     
     xxxbird(*说你行,你就行,不行也行*) 回复于2001-6-27 9:46:31 得0分  
    int size, len;
    len = sizeof(int);getsockopt (s, SOL_SOCKET, SO_MAX_MSG_SIZE, (LPSTR)&size, &len);
     
     xxxbird(*说你行,你就行,不行也行*) 回复于2001-6-27 9:47:45 得0分  
    实际上getsockopt函数对TCP socket不起作用,我上面弄错了。  
     xxxbird(*说你行,你就行,不行也行*) 回复于2001-6-27 9:50:51 得0分  
    >>sendto的buffer是65535那么大(string的极限)>>原来buffer过大引起10040错误,那么buffer应该是多大呢?在我的系统中是65527, 我想加上UDP协议头之后应该正好是65535了。 
     cathy0505() 回复于2001-6-27 9:50:55 得0分  
    int msg_size = 65535;
    getsockopt(s, SOL_SOCKET, SO_MAX_MSG_SIZE, (LPSTR)&msg_size,sizeof(int));oicqsend.c
    C:\WINDOWS\Desktop\oicqsend\oicqsend.c(335) : warning C4047: 'function' : 'int *' differs in levels of indirection from 'unsigned int '
    C:\WINDOWS\Desktop\oicqsend\oicqsend.c(335) : warning C4024: 'getsockopt' : different types for formal and actual parameter 5
    Linking...
    这两个警告又是怎么回事呢?对不起,我初学,什么都不大懂 
     plato(天天) 回复于2001-6-27 9:53:20 得0分  
    UDP包的最大限制是65535个字节  
     cathy0505() 回复于2001-6-27 9:53:39 得0分  
    65527?那int msg_size = 65527;
    但是两个警告怎么处理呢?还不知道这样会不会出现10040错误呢  
     Kevin_qing() 回复于2001-6-27 9:58:48 得0分  
    不好意思,刚才写错了:int msg_size ;
    int size=sizeof(msg_size);
    getsockopt(s, SOL_SOCKET, SO_MAX_MSG_SIZE, (LPSTR)&msg_size,&size);如果成功的话,msg_size 就是你要的东西
     
     xxxbird(*说你行,你就行,不行也行*) 回复于2001-6-27 10:09:00 得0分  
    你需要用getsockopt返回的大小设置你的缓冲区,而不要用硬编码,因为你的系统可能和我的不一样,而且最终用户的系统也有可能和你的不一样。警告的处理可将int msg_size 改为 unsigned int 就可以了。最后一个参数不能用 sizeof.
     
     cathy0505() 回复于2001-6-27 10:37:37 得0分  
    按照Kevin_qing(Kevin) 的方法就没有警告了。
    但运行的结果是,同样出现10040错误我要写的程序是轰炸OICQ之用
    修改了自己的IP
    相关请看
    http://member.netease.com/~wxb/works/oicqsend.htm
    难道发送65535字节大小的数据一定要用tcp连接?难道轰炸OICQ要用tcp连接?
     
     xxxbird(*说你行,你就行,不行也行*) 回复于2001-6-27 10:50:50 得0分  
    哇,动机不纯!你不好一次少发一点么?
     
     field() 回复于2001-6-27 11:03:46 得0分  
    ooh, i love you very much.
     
     runbuff(玩火人) 回复于2001-6-27 13:20:22 得0分  To cathy0505()
      你还是原来的cathy0505()?我怀疑你是盗用别人的ID。
      cathy0505()是一位好MM,怎么说出轰炸OICQ之类令人恐怖的话?! 
     kylix2001(小小&reg;)(我是真的) 回复于2001-6-27 13:36:33 得0分  
    是呀是呀
    :)  
     flywhc(午夜蓝调) 回复于2001-6-27 14:29:27 得0分  
    我想你是把上面那段放一个循环里了?
    考虑用none-blocking的socket, 使用WSAAsyncSelect,在FD_READ的处理中发数据,而发的UDP数据包一般不超过512字节,比较保险。  
     gPolaris(星星之火) 回复于2001-6-27 16:27:21 得0分  
    flywhc(午夜蓝调)说的好  
     lgs(心不在馬) 回复于2001-6-27 16:31:41 得0分  
    sizeof(buffer)错误,
    应该用strlen(buffer)。  
     czylj(夭夭) 回复于2001-6-27 20:14:46 得0分  
    ┏━┯━┓
    ┃夭 夭┃
    ┠ 印 ┨
    ┃夭 夭┃
    ┗━┷━┛  
     wangyi03(小楼一夜听春雨) 回复于2001-6-27 20:20:01 得0分  
    啊,你还会搞这个啊,:))  
     greentea(绿茶) 回复于2001-6-28 9:03:52 得0分  
    具体的错误消息为:
      一个在数据报套接字上发送的消息大于内部消息缓冲器或其它一些网络限制,或该用户用于接收数据报的缓冲器比数据报小。 
      你可以使用vc++6.0-〉tools ->error lookup->键入10040,点击"lookup"就可以看到,
      从错误分析来看,socket内部发送时,维护了一个缓冲,你的缓冲容量显然比socket内部的缓冲要大,建议分包发送,为了提高效率,udp包的大小小于等于256bytes  
     xxxbird(*说你行,你就行,不行也行*) 回复于2001-6-28 9:21:41 得0分  
    理论上一个IP包最大可能有65535字。而UDP是基于IP的,去掉IP头(至少20字节),UDP头(8字节),这样理论上一个UDP包最多就只能发送65507个字节。但在TCP/IP协议栈实际的实现中,很少有达到这个数目的。而且考虑到网络的MTU大小(一般的以太网为1500字节),IP会将大的数据包分段。这样如果数据包过大,将会被分成许多段,这许多段只要有一个在传输过程中出了问题,整个UDP包就会丢失。因此,建议在使用UDP协议时,每次发送的数据量不宜太大,通常以不超过本地的MTU为宜。  
     xianserver(我要学习,你有什么好东西我都要!) 回复于2001-6-28 20:53:38 得0分  
    10040:数据报太大,不适于缓冲区的要求,因而被截断这样简单的方法很简单的就会被防火墙拦截的!  
      

  8.   

    好像好难哦——还是没搞定,也不知道SetSocktOpt函数用对了没有,方正没任何作用int buffersize=8000;
    CString str="192.168.1.38";
    UINT port = 9000;
    int opt,optlen=sizeof(opt);
    ca.m_socket.SetSockOpt(pDoc->m_ca.m_socket.GetSockName(str,port),&buffersize,optlen,IPPROTO_TCP);
    pDoc->m_ca.m_socket.GetSockOpt(pDoc->m_ca.m_socket.GetSockName(str,port),&buffersize,&optlen,IPPROTO_TCP);
      

  9.   

    用WinSock API创建的socket的发送和接收缓冲区的大小默认是0x2000字节,可以用setsockopt设置,不过最大好像只能设到0xff00字节。
    CSocket也差不多吧!
      

  10.   

    有那位高手,可以搞定这个!!!
    http://www.csdn.net/Expert/topic/470/470143.shtm 
      

  11.   

    我用了SetSockOpt,好像也没用,结果为
    10042:
    我得MessageBox()结果为Error Unknown!
    下面是我的VC源代码 int buffersize=2000;
    CString str="192.168.1.38";
    UINT port = 9000;
    int opt,optlen=sizeof(opt);
    if( 0== pDoc->m_ca.m_socket.SetSockOpt(pDoc->m_ca.m_socket.GetSockName(str,port),
    &buffersize,optlen,IPPROTO_TCP) )
    {
    int result = GetLastError();
    int errCode[]={WSANOTINITIALISED,WSAENETDOWN,WSAEFAULT,WSAEINPROGRESS,WSAEINVAL,WSAENETRESET,WSAENOTCONN,WSAENOTSOCK};
    char *err[]={"WSANOTINITIALISED","WSAENETDOWN","WSAEFAULT","WSAEINPROGRESS","WSAEINVAL","WSAENETRESET","WSAENOTCONN","WSAENOTSOCK"};
    int codenum = sizeof(errCode)/sizeof(errCode[0]);
    CString str;
    for(int i=0;i<codenum;i++) if( result==errCode[i] )
    {
    str = err[i];
    break;
    }
    if( i==codenum ) str = "Error Unknown!";
    MessageBox(str,"SetSocketOpt");
    }
      

  12.   

    10042:
    在 getsockopt 或 setsockopt 调用中指定的一个未知的、无效的或不受支持的选项或层次。 
      

  13.   

    确实也是接收端的问题,为什么接收不能超过210各字节的UDP净荷?CSocket的SetSockOpt和GetSockOpt什么情况下可以成功调用?
      

  14.   

    还有就是如何设定CSocket的接收缓冲的大小?to vcbear(一只平凡无知@贫穷无钱¥的熊) 
    该如何解决,有解决之道吗?
      

  15.   

    为什么不把接受端的代码贴出来呢。SetSockOpt封装的是winsockapi的setsockopt,建议参考一下msdn和《windows网络编程技术》关于这个api的叙述
      

  16.   

    有那位高手,可以搞定这个!!!
    http://www.csdn.net/Expert/topic/470/470143.shtm
      

  17.   

    setsockopt 
    (
        hSock,
        SOL_SOCKET ,
        SO_RCVBUF
        ....
    )
      

  18.   

    接收端只有:
    CString hostAddr;
    UINT hostPort;
    char buffer[2048];
    UINT len;
    int len = m_socket.ReceriveFrom(buff,len,hostAddr,hostPort);
    if( len==-1)
    {
        CString error;
        error.Format(“%d",m_socket.GetLastError());
        MessageBox(error);
        return;
    }
    ………………
      

  19.   

    我用
    int buffersize=2048;
    if( 0== pDoc->m_ca.m_socket.SetSockOpt(SO_RCVBUF,&buffersize,sizeof(optlen)) )
    {
        ………………
    }
    也不管用
      

  20.   

    UINT len;
    int len = m_socket.ReceriveFrom(buff,len,hostAddr,hostPort);len要初试话,要不然谁知道你请求读多少字节。len=sizeof(buff);
    UINT len =sizeof(buff);
    int len = m_socket.ReceriveFrom(buff,len,hostAddr,hostPort);
    if( 0== pDoc->m_ca.m_socket.SetSockOpt(SO_RCVBUF,&buffersize,sizeof(optlen)) )
    optlen是什么玩意?
      

  21.   

    谢谢
    与optlen一起定义的一其他变量,随便写的——调试嘛