Winsock缓冲区大小问题
没人知道吗?
昵称: bodybo 时间: 2010-09-29 09:23:44
只修改了自己的缓冲区,别人发过来的包你是改不了的举个例子:
两个Socket缓冲区是仓库,你把自己的仓库改为1024*1024这么大了,别人给你的包裹是8192一个包,难道你想要求人家把8192的包拆开再组合吗?那就不是原来的包了
两个Socket缓冲区是仓库,你把自己的仓库改为1024*1024这么大了,别人给你的包裹是8192一个包,难道你想要求人家把8192的包拆开再组合吗?那就不是原来的包了
昵称: wolfcapita 时间: 2010-09-29 10:37:52
改了自己的缓冲区,只能够说自己这边一次性能够接收1024*1024这么大的包而己。
昵称: wolfcapita 时间: 2010-09-29 10:38:35
DataArrival事件的触发和缓冲区大小无关,因为他的触发过程是和网络协议包的时间有关。
网络接收是这样的,在一定时间(比如500us)内继续收到相对应的数据包,他会将收到的数
据包数据连续的填入缓冲区,但是超出一定时间(比如500us),再异步通讯中他就会触发
FD_READ 消息产生 DataArrival 事件。除非是连续的包太多,他才会根据缓冲区大小来
产生 DataArrival,但通常情况下,不会有那么好的网络条件在路由或交换队列中全是你一
个人的连续作业包。
网络接收是这样的,在一定时间(比如500us)内继续收到相对应的数据包,他会将收到的数
据包数据连续的填入缓冲区,但是超出一定时间(比如500us),再异步通讯中他就会触发
FD_READ 消息产生 DataArrival 事件。除非是连续的包太多,他才会根据缓冲区大小来
产生 DataArrival,但通常情况下,不会有那么好的网络条件在路由或交换队列中全是你一
个人的连续作业包。
昵称: SupermanKing 时间: 2010-09-29 10:44:43
别以为发送端改了缓冲区大小就可以,因为到了底层,还是将数据分成一个一个很小的网络数据包发送的,
因为在硬件层,比如交换机,不可能有那么大的 RAM 来交换那么大量的数据,所以最终还是通过数据交换
协议将数据分割成一个一个很小的数据包在硬件层传输,而且还因为硬件层处理的不只是一个事务,所以
还将这些包按任务队列来分发,在多个小任务交叉执行的时候,看上去好像每个点都能正常同时传输一样,
但是在队列中,如果因为其他的网络信息也需要传输并把任务插入队列,就有可能影响到原来队列中的任务
执行情况,所以对于连续数据包超时产生 FD_READ 消息的时间所包含的已接受缓冲区数量也未必全部相同,
特别是在 Internet 的网络环境中这个问题就特别体现得严重。
昵称: SupermanKing 时间: 2010-09-29 10:59:04
这是我在VB中写的Sock类的一个Send方法,你看看过程就知道什么回事了,
在硬件层的交换,把整个数据还要再分包,那就是正真的网络数据包了。
在硬件层的交换,把整个数据还要再分包,那就是正真的网络数据包了。
-
VB code
-
' ============================================================================== ' 类方法定义及处理过程 ' ============================================================================== ' ******************************************************************************** ' ** 方 法 名 : SendData ' ** 输 入 : data(Variant) - 要通过Sock发送的任何类型数据内容 ' ** 返 回 : 无 ' ** 功能描述 : 发送网络数据 ' ******************************************************************************** Public Sub SendData(data As Variant) Dim SendBuffers() As Byte Dim SendBuffersSize As Long Dim CancelERR As Boolean Dim DataSize As Long Dim SockSendCount As Long Dim SockSendBuffers() As Byte Dim rd As Long ' 将要发送的数据进行字节流格式化 Select Case VarType(data) Case vbString: SendBuffers = StrConv(data, vbFromUnicode) Case vbArray + vbByte: SendBuffers = data End Select SendBuffersSize = UBound(SendBuffers) + 1 ' 取得发送缓冲区大小 rd = api_getsockopt(mvarSocketHandle, _ SOL_SOCKET, _ SO_SNDBUF, _ DataSize, _ 4) If rd = SOCKET_ERROR Then CancelERR = False RaiseEvent SockError(35756, _ "不能完成请求。", _ 0, _ "WinSock.SendData.getsockopt", _ "", _ 0, _ CancelERR) If CancelERR = False Then Err.Raise vbObjectError + 35756, "不能完成请求。", 35756, "", 0 End If Exit Sub End If ' 发送TCP数据 SendMaxSize = DataSize SendNowSize = 0 If SendBuffersSize <= DataSize Then ' 发送的内容小于或等于Sock发送缓冲区的大小,所以进行一次性发送数据 rd = api_send(mvarSocketHandle, SendBuffers(0), SendBuffersSize, 0&) If rd = SOCKET_ERROR Then mvarState = sckError CancelERR = False RaiseEvent SockError(35756, _ "不能完成请求。", _ 0, _ "WinSock.SendData.send", _ "", _ 0, _ CancelERR) If CancelERR = False Then Err.Raise vbObjectError + 35756, "不能完成请求。", 35756, "", 0 End If Exit Sub End If RaiseEvent SendComplete Else ' 自动分包发送数据 SockSendCount = 0 SendMaxSize = SendBuffersSize ReDim SockSendBuffers(DataSize - 1) Do CopyMemory SockSendBuffers(0), SendBuffers(SockSendCount), DataSize AfreshSendData: rd = api_send(mvarSocketHandle, SockSendBuffers(0), DataSize, 0&) If rd = SOCKET_ERROR Then ' 出错重发 GoTo AfreshSendData ElseIf rd = DataSize Then ' 发送成功 Else mvarState = sckError CancelERR = False RaiseEvent SockError(35756, _ "不能完成请求。", _ 0, _ "WinSock.SendData.send", _ "", _ 0, _ CancelERR) If CancelERR = False Then Err.Raise vbObjectError + 35756, "不能完成请求。", 35756, "", 0 End If Exit Sub End If SockSendCount = SockSendCount + DataSize SendNowSize = SockSendCount ' RaiseEvent SendProgress(SendNowSize, SendBuffersSize) If SockSendCount >= SendBuffersSize Then DataSize = 0 Else If SockSendCount + DataSize >= SendBuffersSize Then DataSize = (SendBuffersSize - SockSendCount) End If End If Loop While DataSize > 0 RaiseEvent SendComplete End If End Sub
昵称: SupermanKing 时间: 2010-09-29 11:02:33
VB code-
发送端是用vc写的程序,也设置了发送缓冲区为1024*1024,可在Winsock1_DataArrival接收大数据包时还是接收到按8192分割的数据包,不知为何?难道对winsock控件缓冲区的修改无效吗?