C++/MFC Socket 缓冲区 和 调试 的问题

鄙人网络学的不好,平时也写程序也不会涉及到网络,这些天要谢一个自动升级的通用模块,代码是写完了,可是当服务端把安装包发给客户端之后,客户端接受的数据有时候完整,有时候不完整(收到的数据会小很多),我是对比hash来判断的,程序我看了很多遍始终看不出是什么情况,发现有更新后,我服务端是单独启动一个线程来发送数据,客户端模块也是单独启动一个线程来接收数据(这两个线程除了会发送和接收安装包数据外不会干别的),请问有没有什么办法可以获取或探到TCP发送/接收缓冲区中的内容,我想看看是什么原因导致了这种情况,我现在是不知道服务端有没有发送完整,也不知道接收端有没有接收完整,或者有什么好的调试方法,我真的是无招了,之前觉得这个程序应该很简单,可是现在做了发觉真的折腾死了。

还有很想明确几个问题,把我苦恼很久了,不知道怎么去测试:

(1).TCP发送缓冲区中数据是不是每次都要完整的把整个缓冲区一起全部发送出去,还是如果对方的接收缓冲区有一部分空间nRestSpace可用了,发送缓冲区也会发送nRestSpace字节的数据过去,那如果接收缓冲区剩余空间nRestSpace 小于 发送缓冲区中一个包的大小,发送缓冲区会不会把一个包的一部分先发送到对方的发送缓冲区,等对方接收缓冲区又有空间了再发送那个未发送完的数据包剩余的部分过去,还是在发送缓冲区和接收缓冲区间发送的数据必须是send(s,SendBuff,nlenOSendBuff,0)函数发送出去的一个完整的包(意思就是不会把SendBuff中的数据分开发送,或者重新分割成更小的包发送)。

(2).如果TCP的发送缓冲区还没有满,剩余空间大小为nRestSpace,但是我的send(s,SendBuff,nlenOSendBuff,0),中的buff中的字节数 SendBuff 大于 nRestSpace,这时候如果我调用send(s,SendBuff,nlenOSendBuff,0),会成功吗?或者会把先发送nRestSpace字节的数据到TCP的发送缓冲区中,留下(SendBuff - nRestSpace)字节数据没法送,

(3).如果send(s,SendBuff,nlenOSendBuff,0)中的SendBuff的大小比TCP发送缓冲区的整个大小都大,这是条用send()会出现什么情况。

(4).如果TCP的接收缓冲区被设置的很小比如1024byte,发送缓冲区的大小为2000byte,我用send()一个大小为1500bype的数据过去,会出现什么情况,能发送和接收成功吗?

(5).是不是发送发send(s,SendBuff,nlenOSendBuff,0)的缓冲区SendBuff有多大,接收方就一定要用同等大小(nlenOSendBuff == nlenORecvBuff)的recv(s,RecvBuff,nlenORecvBuff,0)去接收,或者能不能recv把服务器发的一个数据包分成几次接收,或者把接收缓冲区设的很大,一次接收服务器发送的好几个包。

(6).要怎样 设置/协调 TCP的发送缓冲区/接收缓冲区的大小,和send(s,SendBuff,nlenOSendBuff,0),Recv(s,RecvBuff,nlenORecvBuff,0)中SendBuff和RecvBuff,这四者的大小,才能报保证数据发送准确无误。

感激不尽!
...全文
235 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2015-09-24
  • 打赏
  • 举报
回复
赵四出品,必属精品!
  • 打赏
  • 举报
回复
引用 10 楼 cvbtvbwu 的回复:
我做过发送文件的东西,最简单的方法是用TCP进行发送和接收,服务器发文件数据的时候,每次读取文件的一部分如果(如1K数据),然后发送出去,客户端收到数据之后,写入文件,然后返回一个字节给服务器,服务器收到后再进行发送文件其它数据,这样可以不用理Socket缓存区满的问题
谢谢,应该很好,不过还没来得及尝试
引用 7 楼 linyudekongqi 的回复:
[quote=引用 5 楼 zhao4zhong1 的回复:] 仅供参考:
void HexDump(char *buf,int len,int addr) {
    int i,j,k;
    char binstr[80];

    for (i=0;i<len;i++) {
        if (0==(i%16)) {
            sprintf(binstr,"%08x -",i+addr);
            sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
        } else if (15==(i%16)) {
            sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
            sprintf(binstr,"%s  ",binstr);
            for (j=i-15;j<=i;j++) {
                sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');
            }
            printf("%s\n",binstr);
        } else {
            sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
        }
    }
    if (0!=(i%16)) {
        k=16-(i%16);
        for (j=0;j<k;j++) {
            sprintf(binstr,"%s   ",binstr);
        }
        sprintf(binstr,"%s  ",binstr);
        k=16-k;
        for (j=i-k;j<i;j++) {
            sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');
        }
        printf("%s\n",binstr);
    }
}
这个函数不知道如何派上用,好像只是把数据转化成十六进制的,不过很想问一下,wireshark里面抓的包的内容,如果我不对发送的数据进行加密的话,TCP协议在发送的时候会把它加密吗(会有加密这个过程吗)?[/quote] 还是很感谢你贴上的代码,以前也看过几次你贴的代码也用过很有价值,wireshark的方法还没来得及查完,现在(就是刚才)已经想到一个很简单的测试方法了,设置各种条件发最简单的测试,不过你给这段代码还真的用上了,用来dump接收的内容可以和原内容比较看看是不是期望的,还是得亲自验证才知道啊,已经开始有点感觉了,还在测试中......
叶恭介叶恭介 2015-09-24
  • 打赏
  • 举报
回复
我做过发送文件的东西,最简单的方法是用TCP进行发送和接收,服务器发文件数据的时候,每次读取文件的一部分如果(如1K数据),然后发送出去,客户端收到数据之后,写入文件,然后返回一个字节给服务器,服务器收到后再进行发送文件其它数据,这样可以不用理Socket缓存区满的问题
  • 打赏
  • 举报
回复
这方面的资料不好找啊
ArthurKingYs 2015-09-23
  • 打赏
  • 举报
回复
通过什么传送 外网内网?
  • 打赏
  • 举报
回复
引用 5 楼 zhao4zhong1 的回复:
仅供参考:
void HexDump(char *buf,int len,int addr) {
    int i,j,k;
    char binstr[80];

    for (i=0;i<len;i++) {
        if (0==(i%16)) {
            sprintf(binstr,"%08x -",i+addr);
            sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
        } else if (15==(i%16)) {
            sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
            sprintf(binstr,"%s  ",binstr);
            for (j=i-15;j<=i;j++) {
                sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');
            }
            printf("%s\n",binstr);
        } else {
            sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
        }
    }
    if (0!=(i%16)) {
        k=16-(i%16);
        for (j=0;j<k;j++) {
            sprintf(binstr,"%s   ",binstr);
        }
        sprintf(binstr,"%s  ",binstr);
        k=16-k;
        for (j=i-k;j<i;j++) {
            sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');
        }
        printf("%s\n",binstr);
    }
}
这个函数不知道如何派上用,好像只是把数据转化成十六进制的,不过很想问一下,wireshark里面抓的包的内容,如果我不对发送的数据进行加密的话,TCP协议在发送的时候会把它加密吗(会有加密这个过程吗)?
  • 打赏
  • 举报
回复
没人回答,不会都是不知道吧???
赵4老师 2015-09-22
  • 打赏
  • 举报
回复
仅供参考:
void HexDump(char *buf,int len,int addr) {
    int i,j,k;
    char binstr[80];

    for (i=0;i<len;i++) {
        if (0==(i%16)) {
            sprintf(binstr,"%08x -",i+addr);
            sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
        } else if (15==(i%16)) {
            sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
            sprintf(binstr,"%s  ",binstr);
            for (j=i-15;j<=i;j++) {
                sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');
            }
            printf("%s\n",binstr);
        } else {
            sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
        }
    }
    if (0!=(i%16)) {
        k=16-(i%16);
        for (j=0;j<k;j++) {
            sprintf(binstr,"%s   ",binstr);
        }
        sprintf(binstr,"%s  ",binstr);
        k=16-k;
        for (j=i-k;j<i;j++) {
            sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');
        }
        printf("%s\n",binstr);
    }
}
  • 打赏
  • 举报
回复
引用 3 楼 zhao4zhong1 的回复:
楼主要不先学会使用抓包软件比如wireshark
刚看了你那个连接,确实很给力很激烈,没解决我的问题,不过还是受益匪浅,我的程序里面也确实使用了里面说的包什么的那个东西,wireshark正在抽时间琢磨,不知道我学会了使用wireshark,通过它能验证我的那些问题吗,其实我也写代码测试了一个,只是我还是不太相信自己的能力,之前没接触过网络编程,我确实很想验证下上面那些问题,但是不知道要怎么去做,也看不到我发的内容,靠我写程序验证,太不可靠了,我都不相信自己了。 现在程序是可以用了,不过对于我的那几点疑虑,不知道你还有什么更好的建议和看法,会用wireshark就可以看到包里面的数据吗?可不可以有什么方法直接看到缓冲区中的内容。
赵4老师 2015-09-22
  • 打赏
  • 举报
回复
楼主要不先学会使用抓包软件比如wireshark
信阳毛尖 2015-09-22
  • 打赏
  • 举报
回复
这问题提的,貌似我也不会socket了
赵4老师 2015-09-22
  • 打赏
  • 举报
回复
不知道有多少前人掉在TCP Socket send(人多)send(病少)send(财富) recv(人多病)recv(少财富) 陷阱里面啊! http://bbs.csdn.net/topics/380167545

18,356

社区成员

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

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