winsock缓冲区大小

繁體中文 English
用户名:   密码:      忘记密码?  登陆  注册

首页 | 新闻 | 交流 | 问吧 | 文档 | 手册 | 下载 | 博客

 

Winsock缓冲区大小问题

windsock缓冲区大小默认为8192字节,尝试用API函数setsocketopt修改,似乎也修改成功了,代码如下:
VB code
      
      
Dim lResult As Long Dim bufSize As Long bufSize = CLng(1024) * 1024 lResult = setsockopt(Winsock1.SocketHandle, SOL_SOCKET, SO_RCVBUF, bufSize, 4) If (lResult = SOCKET_ERROR) Then MsgBox "Error setting SO_RCVBUF option: " & CStr(Err.LastDllError) End If lResult = setsockopt(Winsock1.SocketHandle, SOL_SOCKET, SO_SNDBUF, bufSize, 4) If (lResult = SOCKET_ERROR) Then MsgBox "Error setting SO_SNDBUF option: " & CStr(Err.LastDllError) End If bufSize = 0 lResult = getsockopt(Winsock1.SocketHandle, SOL_SOCKET, SO_RCVBUF, bufSize, 4) If (lResult = SOCKET_ERROR) Then MsgBox "Error getting SO_RCVBUF option: " & CStr(Err.LastDllError) End If ' bufSize=1024*1024,说明设置成功


发送端是用vc写的程序,也设置了发送缓冲区为1024*1024,可在Winsock1_DataArrival接收大数据包时还是接收到按8192分割的数据包,不知为何?难道对winsock控件缓冲区的修改无效吗?
昵称: bodybo  时间: 2010-09-28 13:08:50
没人知道吗?
昵称: bodybo  时间: 2010-09-29 09:23:44
只修改了自己的缓冲区,别人发过来的包你是改不了的举个例子:
两个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,但通常情况下,不会有那么好的网络条件在路由或交换队列中全是你一
个人的连续作业包。
昵称: SupermanKing  时间: 2010-09-29 10:44:43
引用 2 楼 wolfcapita 的回复:
只修改了自己的缓冲区,别人发过来的包你是改不了的举个例子:
两个Socket缓冲区是仓库,你把自己的仓库改为1024*1024这么大了,别人给你的包裹是8192一个包,难道你想要求人家把8192的包拆开再组合吗?那就不是原来的包了

别以为发送端改了缓冲区大小就可以,因为到了底层,还是将数据分成一个一个很小的网络数据包发送的,
因为在硬件层,比如交换机,不可能有那么大的 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
 

 
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值