SOCKET 发送数据

wozhaozhe2008 2021-05-20 09:54:25
我想问下,我写了一个SOCKET TCP的程序,在本地好好的
但放到服务器里,会少几个字节,导致文件打不开,
我是Client每次发送1024字节,Server接受也是1024字节,也就是说有多少,我接收多少。
我并没有弄什么包头之类的,因为我每次必须发完才能操作,所以不需要那些信息。
现在的问题是,我发送过去了,那边也接受到了,为什么会丢失字节呢,
200多KB会丢失大约10来个字节。不确定。

我查了资料,唯一说到的就是什么半包,粘包,按道理我不会啊,Client发多少,Server就接收多少,我并不需要判断多少字节,反正你来多少字节我要多少字节
...全文
24567 30 打赏 收藏 转发到动态 举报
写回复
用AI写文章
30 条回复
切换为时间正序
请发表友善的回复…
发表回复
TOP3098 2021-05-26
  • 打赏
  • 举报
回复
猜测是代码有问题
mbhh_1883 2021-05-26
  • 打赏
  • 举报
回复
都是高手啊csndkjhs'
weixin_47047402 2021-05-25
  • 打赏
  • 举报
回复
没有代码无法评价
foenix66 2021-05-24
  • 打赏
  • 举报
回复
引用 9 楼 wozhaozhe2008 的回复:
[quote=引用 6 楼 wanghui0380 的回复:]没有代码无法评价

只能说大概可能的猜测 int i=socket.receiveXXXX(buffer,1024) 并不等于就一定收了1024,即使你号称不拆包,不解包,没有半包,没有粘包。

ps:不知道你的代码如何,但从你的描述上来看,你的东西叫固定长度封包,而不是你想的什么“没有包头,包尾就不叫封包,不用解包”
客户端那边发送多少,我服务器全盘接收,现在问题是客户端发送过来变少了,客服端确实发送了1024字节,但服务器只收到了997字节[/quote]
下一个包还有27个字节数据。应该用的是UDP通讯吧,理论单帧长度是1500字节,去掉包头数据字节还有1400多个,但实际因特网上,要保证不被拆包的最大包长度最好不超过500字节(一种说法是Internet上标准MTU值为576字节)。
hudi0719 2021-05-23
  • 打赏
  • 举报
回复
参考一下参考一下
unbelievabler 2021-05-22
  • 打赏
  • 举报
回复
finalfantasy_xu 2021-05-22
  • 打赏
  • 举报
回复
没法评价,只能等详细资料
xiaoxiangqing 2021-05-22
  • 打赏
  • 举报
回复
正常来说,不会出现这种现象
远方Alan 2021-05-22
  • 打赏
  • 举报
回复
丢包不会重传
wozhaozhe2008 2021-05-21
  • 打赏
  • 举报
回复
引用 13 楼 wanghui0380 的回复:
对于发送文件来说,这种定不定长根本无所谓 很简单,就算你是1024一发,你也不能保证文件都是1024得整数倍 假设最后只剩720字节了,不够1024怎么办,当然还是继续传(无论是同步还是异步),是如果他不出异常,我们认为他全部传输成功,然后自己主动断掉tcp 所以正常情况是,假设每次传输都说单独发起一个连接(一个client没有并行发送文件),那么就你只管往里面写就好。 默认配置一个套接字,你send其实并不是真正的发,他只是写入你本地内存缓冲,然后网卡驱动通过dma方式直接读取并发送(所以这里你看到了,网卡其实并不管你是不是1024写入了,只要你有IRQ请求了,中断被触发了,那个缓冲区有可读区域他就读,他就发。压根就不管你缓冲区是不是1024) 所以如果是这种模式下,你无需纠结是否1024一次,你只管不停的send到缓冲区即可。 而server端,只需要不停写入到一个临时文件,然后client断开把临时文件重命名成正式文件(对,我这里假设一个client就发一个文件,所以你可以用断开当条件,但是如果你要不停顺序发文件,那么很明显server端无法知道前后两个文件的分割点,所以需要约定协议保证) 当然所有的描述都说理想情况,而做网络通讯的其实大部分时间在处理异常情况,虽然异常很少发生,但是一但他发生你就有问题了 比如:网络断线,网络不稳定,数据传输途中错误。 所以我们才用协议去保证。头,内容长度,校验位。 类似rstp这种甚至还有总包,分包,索引等去保证 扩展描述:虽然异常很少发生,但是一但他发生你就有问题了---------------比如你发了一半,网络断了,server端怎么办,我们上面没有协议保证,就单纯输出字节,server端也无法判定是传完了,还是没传完。当然我们可以通过state判定是网络断开还是你主动close的,但是这种判定多少显得不那么保险)
我现在就是你说的那种,Server只管往临时文件写,可现在遇到会少字节的问题
wanghui0380 2021-05-21
  • 打赏
  • 举报
回复 1
对于发送文件来说,这种定不定长根本无所谓 很简单,就算你是1024一发,你也不能保证文件都是1024得整数倍 假设最后只剩720字节了,不够1024怎么办,当然还是继续传(无论是同步还是异步),是如果他不出异常,我们认为他全部传输成功,然后自己主动断掉tcp 所以正常情况是,假设每次传输都说单独发起一个连接(一个client没有并行发送文件),那么就你只管往里面写就好。 默认配置一个套接字,你send其实并不是真正的发,他只是写入你本地内存缓冲,然后网卡驱动通过dma方式直接读取并发送(所以这里你看到了,网卡其实并不管你是不是1024写入了,只要你有IRQ请求了,中断被触发了,那个缓冲区有可读区域他就读,他就发。压根就不管你缓冲区是不是1024) 所以如果是这种模式下,你无需纠结是否1024一次,你只管不停的send到缓冲区即可。 而server端,只需要不停写入到一个临时文件,然后client断开把临时文件重命名成正式文件(对,我这里假设一个client就发一个文件,所以你可以用断开当条件,但是如果你要不停顺序发文件,那么很明显server端无法知道前后两个文件的分割点,所以需要约定协议保证) 当然所有的描述都说理想情况,而做网络通讯的其实大部分时间在处理异常情况,虽然异常很少发生,但是一但他发生你就有问题了 比如:网络断线,网络不稳定,数据传输途中错误。 所以我们才用协议去保证。头,内容长度,校验位。 类似rstp这种甚至还有总包,分包,索引等去保证 扩展描述:虽然异常很少发生,但是一但他发生你就有问题了---------------比如你发了一半,网络断了,server端怎么办,我们上面没有协议保证,就单纯输出字节,server端也无法判定是传完了,还是没传完。当然我们可以通过state判定是网络断开还是你主动close的,但是这种判定多少显得不那么保险)
wozhaozhe2008 2021-05-21
  • 打赏
  • 举报
回复
引用 11 楼 ziqi0716 的回复:
劝你还是先看看这些概念再处理.假如是练习,你不管这些断包,粘包,数据校验等问题,无所谓,但是如果是工作,你绕不开的.
就是想弄一个小工具,工作不是这方向的。
ziqi0716 2021-05-21
  • 打赏
  • 举报
回复
劝你还是先看看这些概念再处理.假如是练习,你不管这些断包,粘包,数据校验等问题,无所谓,但是如果是工作,你绕不开的.
wozhaozhe2008 2021-05-21
  • 打赏
  • 举报
回复
引用 7 楼 wanghui0380 的回复:
即使是楼上说那个Hp sockect,我们来看看他得说法 https://gitee.com/chenrongda/HPSocket.Net FixedSizeDataReceiveAdapter 定长包数据接收适配器 他会告诉你“即使是定长数据,也得用专有适配器去解包”
好的,我查一下资料看看,我一直认为我分多次发送1m大小的数据,那边的分多少接收就行。我定义发送和接收都是1024大小
wozhaozhe2008 2021-05-21
  • 打赏
  • 举报
回复
引用 6 楼 wanghui0380 的回复:
没有代码无法评价 只能说大概可能的猜测 int i=socket.receiveXXXX(buffer,1024) 并不等于就一定收了1024,即使你号称不拆包,不解包,没有半包,没有粘包。 ps:不知道你的代码如何,但从你的描述上来看,你的东西叫固定长度封包,而不是你想的什么“没有包头,包尾就不叫封包,不用解包”
客户端那边发送多少,我服务器全盘接收,现在问题是客户端发送过来变少了,客服端确实发送了1024字节,但服务器只收到了997字节
wozhaozhe2008 2021-05-21
  • 打赏
  • 举报
回复
引用 5 楼 LiveShare_Mr_Dang 的回复:
client一次发多少,server接收多少,一般来说是这样的,但是server可能会存在一个包接收2次以上的情况,你是不是这个情况没有处理?
应该不会出现这种情况吧,反正没接受完会继续接收。
wanghui0380 2021-05-21
  • 打赏
  • 举报
回复
即使是楼上说那个Hp sockect,我们来看看他得说法 https://gitee.com/chenrongda/HPSocket.Net FixedSizeDataReceiveAdapter 定长包数据接收适配器 他会告诉你“即使是定长数据,也得用专有适配器去解包”
wanghui0380 2021-05-21
  • 打赏
  • 举报
回复
没有代码无法评价 只能说大概可能的猜测 int i=socket.receiveXXXX(buffer,1024) 并不等于就一定收了1024,即使你号称不拆包,不解包,没有半包,没有粘包。 ps:不知道你的代码如何,但从你的描述上来看,你的东西叫固定长度封包,而不是你想的什么“没有包头,包尾就不叫封包,不用解包”
Mr Dang 2021-05-21
  • 打赏
  • 举报
回复
client一次发多少,server接收多少,一般来说是这样的,但是server可能会存在一个包接收2次以上的情况,你是不是这个情况没有处理?
冰思雨 2021-05-21
  • 打赏
  • 举报
回复
没有代码,无法定位具体问题。 楼主在编程的时候要注意以下几点: 1. 发送和接收的缓冲区,可以相同,也可以不同,结果并不会有影响,只是速度快慢的问题。 2. 发送过程,数据最好每次都发送一个被写满的缓冲区,因为发送的数据是从硬盘读取出来的,所以,每次读取,有可能会填不满缓冲区的情况。每次发送,都要确定具体发送的量,不可以填充了半个缓冲区,然后发送整个缓冲区的数据,这样的话,数据就不一致的了。 3. 每次发送完毕,最好要进行一次 flush 操作,传说中的冲马桶操作,可以刷新操作系统底层的缓存,保证接收端及时收到数据。 4. 接收端每次接收的数据也要进行计数,很多人都认为每次接收的数据必然会填满缓冲区,这不是必然的情况,TCP是流,有时候你收到的数据没有填满缓冲区,只填充了半个,那,时候,你要保存缓冲区的大小,然后,根据这个大小,再写入文件当中,每次都要这样干。 5. 客户端发送完毕,要进行 flush 和 close 两个操作,不要强制退出程序,因为,操作系统底层会维持TCP连接,你要是直接退出程序,就会丢失最后的数据。 最好是搞个自定义的通信协议,设置包头包体的传,可以先传文件名和大小,然后在传数据。 为了省事的话,就要做好我上面说的五个要点。
加载更多回复(10)

110,538

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

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