C#.网络编程 Socket基础(九)内网: socket.send(btButterSend)发送、socket.receive(btButterRec)接收,但是接收的速率很慢,
一、所遇到的问题
视频监控,本机利用 socket.send(btButterSend)发送, socket.receive(btButterRec)接收,就能实时的实现视频监控。其中,一幅图=921654个字节。但是在公司的局域网试了下,发现接收端的收到的数据太慢了。收到的字节如下:
于是,ping xx.xx.xx.xx -t(WLAN内网)
ping内网
内网的时延甚至比外网的时延还大。为什么呢?我还不死心,于是再ping了内网(以太网),时延很小,但是收到的数字包还是很小,说明不是局域网的问题。
二、如何判断网络快不快?(比如玩王者荣耀需要小于100ms)
ping www.baidu.com -t(ping百度,外网)
ms越小越快。
1~30ms:极快,几乎察觉不出有延迟,玩任何游戏速度都特别顺畅
31~50ms:良好,可以正常游戏,没有明显的延迟情况
51~100ms:普通,对抗类游戏能感觉出明显延迟,稍有停顿
>100ms:差,无法正常游戏,有卡顿,丢包并掉线现象
计算方法:1秒=1000毫秒(例:30ms为0.03秒)
三、socket数据发送与接收问题
参考:https://blog.****.net/yangkunqiankun/article/details/75943596
socket缓冲区
每一个socket在被创建之后,系统都会给它分配两个缓冲区,即输入缓冲区和输出缓冲区。
send函数并不是直接将数据传输到网络中,而是负责将数据写入输出缓冲区,数据从输出缓冲区发送到目标主机是由TCP协议完成的。数据写入到输出缓冲区之后,send函数就可以返回了,数据是否发送出去,是否发送成功,何时到达目标主机,都不由它负责了,而是由协议负责。
recv函数也是一样的,它并不是直接从网络中获取数据,而是从输入缓冲区中读取数据。
输入输出缓冲区,系统会为每个socket都单独分配,并且是在socket创建的时候自动生成的。一般来说,默认的输入输出缓冲区大小为8K。套接字关闭的时候,输出缓冲区的数据不会丢失,会由协议发送到另一方;而输入缓冲区的数据则会丢失。
socket数据发送与接收问题
数据的发送和接收是独立的,并不是发送方执行一次send,接收方就执行以此recv。recv函数不管发送几次,都会从输入缓冲区尽可能多的获取数据。如果发送方发送了多次信息,接收方没来得及进行recv,则数据堆积在输入缓冲区中,取数据的时候会都取出来。换句话说,recv并不能判断数据包的结束位置。
send函数:
在数据进行发送的时候,需要先检查输出缓冲区的可用空间大小,如果可用空间大小小于要发送的数据长度,则send会被阻塞,直到缓冲区中的数据被发送到目标主机,有了足够的空间之后,send函数才会将数据写入输出缓冲区。
TCP协议正在将数据发送到网络上的时候,输出缓冲区会被锁定(生产者消费者问题),不允许写入,send函数会被阻塞,直到数据发送完,输出缓冲区解锁,此时send才能将数据写入到输出缓冲区。
要写入的数据大于输出缓冲区的最大长度的时候,要分多次写入,直到所有数据都被写到缓冲区之后,send函数才会返回。
recv函数:
函数先检查输入缓冲区,如果输入缓冲区中有数据,读取出缓冲区中的数据,否则的话,recv函数会被阻塞,等待网络上传来数据。如果读取的数据长度小于输出缓冲区中的数据长度,没法一次性将所有数据读出来,需要多次执行recv函数,才能将数据读取完毕。
四、别人和我遇到了同样的问题
https://20921556.iteye.com/blog/1013967
https://bbs.****.net/topics/390262143