Results 1 to 21 of 21

Thread: Iocp Server by vb6

  1. #1

    Thread Starter
    PowerPoster
    Join Date
    Jan 2020
    Posts
    3,749

    Iocp Server by vb6

    "This should be considered a very simple server, with many functions not implemented, and only one framework. I don't think there are many people who need this thing, but I have spent a lot of time researching this thing (I have only seen it for 3 years and practiced it for 30 years to reach today's situation). Therefore, if you download the code, you must give me points."
    "Personally, I think the performance of this device should be quite good (the number of bursts should be better than the winsock control). It can achieve 10W of IO per second, and it also has a memory pool implemented to avoid memory fragmentation, which is not bad in terms of stability. However, it is much more difficult to truly write a specific application than the winsock control, but the performance it brings is indeed worth it."

    FROM :http://www.vbgood.com/thread-97360-1-1.html

    A simple application using I/O Completion Ports and WinSock - CodeProject
    https://www.codeproject.com/articles...etion-ports-an

    https://www.codeproject.com/articles...r-client-class


    form1.frm
    Code:
    Private Sub Form_Load()
            
            Dim i As Long
            
            If Initsockdll() = False Then
                    MsgBox "Init socket dll err"
    
                    End
    
            End If
    
            Dbgprint "Successfully initialized Winsock"
    
            hIOCP = CreateIOCP()
    
            If hIOCP = 0 Then
                    MsgBox "Create IOCP err"
    
                    End
    
            End If
    
            Dbgprint "Create IOCP Port Successfully " & hIOCP
            hListenSck = CreateSocket
    
            If hListenSck = INVALID_SOCKET Then
                    MsgBox "Create socket err"
    
                    End
    
            End If
    
            Dbgprint "Successfully created the socket"
    
            If BindServerSocket(hListenSck, 5150, "") = False Then
                    MsgBox "bind err"
    
                    End
    
            End If
    
            Dbgprint "Bind to Port 5150 Successfully"
    
            Dim lpThreadId As Long
    
            Dbgprint "Start worker thread"
    
            hThread(0) = CreateThread(0, 0, AddressOf ListenFunc, ByVal 0&, 0, lpThreadId) '监听线程
                    
            '这里是固定好的12个线程 但是在实际应用中这个应该根据CPU的数目或者实际测试得出具体数目
                    
            For i = 1 To 12
                    hThread(i) = CreateThread(0, 0, AddressOf WorkFunc, ByVal 0&, 0, lpThreadId)
            Next
            
            Dbgprint "Startup complete port 5150"
    End Sub
    
    Private Sub Form_Unload(Cancel As Integer)
    
            Dim i As Long
    
            For i = 0 To 13
                    TerminateThread hThread(i), 0
            Next
    
    End Sub
    Private Sub Timer1_Timer()
    
            Dim Speed As Long
    
            txtText6.Text = InterlockedExchange(SendPackageCount, 0)
            txtText7.Text = InterlockedExchange(RecvPackageCount, 0)
            txtText8.Text = Val(txtText6.Text) + Val(txtText7.Text)
    
            txtText2.Text = Round(InterlockedExchange(SendBytesCount, 0) / 1024, 3)
            txtText3.Text = Round(InterlockedExchange(RecvBytesCount, 0) / 1024, 3)
            txtText9.Text = Val(txtText3.Text) + Val(txtText2.Text) & "KB/S"
            txtText5.Text = PerDataCount
            txtText4.Text = ClientCount
    End Sub
    Attached Files Attached Files
    Last edited by xiaoyao; Mar 20th, 2023 at 03:51 AM.

  2. #2

    Thread Starter
    PowerPoster
    Join Date
    Jan 2020
    Posts
    3,749

    Re: Iocp Server by vb6

    IOCP.bas

    Code:
    '======================================================================================
    '模块说明: IOCP
    '开发人员: 菜鸟学飞 & 专业路过
    '创建时间: 2010-10-2
    '博    客: http://hi.baidu.com/专业路过_H/home
    '邮    箱: Professionalpassing@gmail.com
    '版权说明: 本模块可以用于任何目的 但请保留此版权信息,谢谢。
    '======================================================================================
    
    Option Explicit
    Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
    
    Public Declare Sub ZeroMemory Lib "kernel32" Alias "RtlMoveMemory" (dest As Any, ByVal numBytes As Long)
    
    Public Declare Function InterlockedDecrement Lib "kernel32" (ByRef lpAddend As Long) As Long
    
    Public Declare Function InterlockedExchange Lib "kernel32" (Target As Long, ByVal Value As Long) As Long
    
    Public Declare Function InterlockedIncrement Lib "kernel32" (ByRef lpAddend As Long) As Long
    
    Public Declare Function InterlockedCompareExchange Lib "kernel32" (Destination As Long, ByVal Exchange As Long, ByVal Comperand As Long) As Long
    
    Public Declare Function InterlockedExchangeAdd Lib "kernel32" (Addend As Long, ByVal Value As Long) As Long
    
    Public Declare Sub EnterCriticalSection Lib "kernel32" (lpCriticalSection As CRITICAL_SECTION)
    
    Public Declare Sub InitializeCriticalSection Lib "kernel32" (lpCriticalSection As CRITICAL_SECTION)
    
    Public Declare Sub LeaveCriticalSection Lib "kernel32" (lpCriticalSection As CRITICAL_SECTION)
    
    Public Declare Function CreateIoCompletionPort Lib "kernel32" (ByVal FileHandle As Long, ByVal ExistingCompletionPort As Long, ByVal CompletionKey As Long, ByVal NumberOfConcurrentThreads As Long) As Long
    
    Public Declare Function GetQueuedCompletionStatus Lib "kernel32" (ByVal CompletionPort As Long, ByRef lpNumberOfBytesTransferred As Long, ByRef lpCompletionKey As Long, ByRef lpOverlapped As Long, ByVal dwMilliseconds As Long) As Long
    
    Public Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hwnd As Long, ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long
    
    '   8B4424 04       mov     eax, dword ptr [esp+4]
    '   8B00            mov     eax, dword ptr [eax]
    '   C2 0400         retn    4
    Public Asmbin1(13) As Byte
    
    '8B4424 04       mov     eax, dword ptr [esp+4]
    '0FB600          movzx   eax, byte ptr [eax]
    'C2 0400         retn    4
    Public Asmbin2(13) As Byte
    
    
    Public Const INVALID_HANDLE_VALUE = -1
    
    Public Const INFINITE = &HFFFF
    
    Public Type CRITICAL_SECTION
            DebugInfo As Long
            LockCount As Long
            RecursionCount As Long
            OwningThread As Long
            LockSemaphore As Long
            SpinCount As Long
    
    End Type
    
    Public Type OVERLAPPED
    
            Internal As Long
            InternalHigh As Long
            Offset As Long
            OffsetHigh As Long
            hEvent As Long
    
    End Type
    
    Public Enum IOType
    
            IOAccept
            IOSend
            IORecv
            IORecvZero
            IOClose
    
    End Enum
    
    Public Type ClientListStruct
    
            tag As Long                 '保存数组索引
            sck As Long                 '保存客户端socket
            ip  As Long                 '保存客户端IP
    
    End Type
    
    Public Type PerDataStruct
    
            tag As Long                 '保存数组索引
            ovlap As OVERLAPPED         '这个结构初始化的时候要清零 (不知道是不是每次操作都要清零 反正我是每次投递操作都做了清零的)
            operation As IOType         '保存 IO操作类型
            nLen As Long                '保存数据长度
            buf(1023) As Byte           '数据缓冲区
    
    End Type
    
    Public FormLock As CRITICAL_SECTION '输出调试信息的所
    
    Public Logcount As Long             '调试信息总条数 数目太多就清空
    
    Public Const MAX_PERBUFLEN = 1024 '单 IO数据 buf长度
    
    Public PerDataCount As Long     '剩余空闲 单IO数据 总数
    
    Public Const MAX_PERDATACOUNT = 100000
    
    Public ClientCount As Long      '剩余空闲 客户端数据结构 总数
    
    Public Const MAX_CLIENTCOUNT = 10000 '最大连接数
    
    Public hIOCP As Long            '完成端口句柄
    
    Public hListenSck As Long       '服务器监听socket
    
    Public nThreadCount As Long     '线程总数 这里还没用到
    
    Public hThread(16) As Long      '工作线程句柄
    
    Public PerData() As PerDataStruct '单IO数据结构
    
    Public Clientlist() As ClientListStruct '存储客户端信息的结果 包括客户端socket ip等
    
    Public SendPackageCount As Long         '发送数据包总数
    
    Public RecvPackageCount As Long         '接收数据包总数
    
    Public SendBytesCount As Long           '发送数据字节数
    
    Public RecvBytesCount As Long           '接收数据字节数
    
    Sub Main()
    
            Dim i As Long
    
            InitializeCriticalSection FormLock
            
            PerDataCount = MAX_PERDATACOUNT
            ClientCount = MAX_CLIENTCOUNT
            
            ReDim PerData(MAX_PERDATACOUNT)
            ReDim Clientlist(MAX_CLIENTCOUNT)
            
            Asmbin1(0) = &H8B
            Asmbin1(1) = &H44
            Asmbin1(2) = &H24
            Asmbin1(3) = &H4
            Asmbin1(4) = &H8B
            Asmbin1(5) = &H0
            Asmbin1(6) = &HC2
            Asmbin1(7) = &H4
            Asmbin1(8) = &H0
            
            Asmbin2(0) = &H8B
            Asmbin2(1) = &H44
            Asmbin2(2) = &H24
            Asmbin2(3) = &H4
            Asmbin2(4) = &HF
            Asmbin2(5) = &HB6
            Asmbin2(6) = &H0
            Asmbin2(7) = &HC2
            Asmbin2(8) = &H4
            Asmbin2(9) = &H0
            
            '8B4424 04       mov     eax, dword ptr [esp+4]
            '8B00            mov     eax, dword ptr [eax]
            'C2 0400         retn    4
            WriteProcessMemory -1, ByVal TmpGetAddr(AddressOf GetPointInt), Asmbin1(0), 9, i
    
            '8B4424 04       mov     eax, dword ptr [esp+4]
            '0FB600          movzx   eax, byte ptr [eax]
            'C2 0400         retn    4
            WriteProcessMemory -1, ByVal TmpGetAddr(AddressOf GetPointByte), Asmbin2(0), 10, i
    
            Form1.Show
    End Sub
    
    Public Function Dbgprint(ByVal log As String) As Long '输出调试信息
            EnterCriticalSection FormLock
            Logcount = Logcount + 1
    
            If Logcount >= 500 Then
                    Logcount = 0
                    Form1.txtText1.Text = ""
            End If
    
            Form1.txtText1.Text = log + vbNewLine + Form1.txtText1.Text
            LeaveCriticalSection FormLock
    End Function
    
    Public Function NewPerData() As Long '分配1个空闲的单IO数据出来 返回的是空闲数据的数组 索引
    
            Dim i As Long
    
            Dim nRet As Long
    
            For i = 1 To MAX_PERDATACOUNT
                    'tag=0 表示这个单元为空闲 可以分配出去 分配出去后 tag改成数组的索引
                    If PerData(i).tag = 0 Then
                    
                            nRet = InterlockedCompareExchange(PerData(i).tag, i, 0) '这里作线程同步 不解释. 详见MSDN
                            
                            '如果 nRet<> 0 则说明有人提前分配出去了 直接找下一个空闲的单元
                            If nRet = 0 Then
                                    InterlockedDecrement PerDataCount
                                    NewPerData = i
    
                                    Exit Function
    
                            End If
                    End If
    
            Next
    
            NewPerData = -1
    End Function
    
    Public Function ReleasePerData(ByVal i As Long) As Long '回收释放数据 参数是数据数组索引
            Dim nRet As Long
            nRet = InterlockedCompareExchange(PerData(i).tag, 0, i) ',这里作线程同步 不解释.实际上这里不用线程同步应该也可以的
            InterlockedIncrement PerDataCount                       '计数
    End Function
    
    Public Function NewClient() As Long '分配1个空闲的客户端数据出来 返回的是空闲数据的数组 索引
    
            Dim i As Long
    
            Dim nRet As Long
    
            For i = 1 To MAX_CLIENTCOUNT
                    '所有注释同上
                    If Clientlist(i).tag = 0 Then
                            nRet = InterlockedCompareExchange(Clientlist(i).tag, i, 0)
    
                            If nRet = 0 Then
                                    InterlockedDecrement ClientCount
                                    NewClient = i
    
                                    Exit Function
    
                            End If
                    End If
    
            Next
    
            NewClient = -1
    End Function
    
    Public Function ReleaseClient(ByVal i As Long) As Long '回收释放数据 参数是数据数组索引
    
            Dim nRet As Long
    
            closesocket Clientlist(i).sck           '释放socket
            
            '        Dim ip As String
            '        ip = Str(GetPointByte(VarPtr(Clientlist(i).ip))) + "." + Str(GetPointByte(VarPtr(Clientlist(i).ip) + 1)) + "." + Str(GetPointByte(VarPtr(Clientlist(i).ip) + 2)) + "." + Str(GetPointByte(VarPtr(Clientlist(i).ip) + 3))
            '        Dbgprint ("IP" + ip + "断开   销毁内存" & i)
            
            nRet = InterlockedCompareExchange(Clientlist(i).tag, 0, i)
            
            InterlockedIncrement ClientCount
    End Function
    
    Public Function GetPointInt(ByVal p As Long) As Long '从一个指针返回长整形 这里会在初始化的时候进行硬编码 详见 sub main
            Dim nRet As Long
            CopyMemory nRet, ByVal p, 4
            GetPointInt = nRet
    End Function
    
    Public Function GetPointByte(ByVal p As Long) As Byte '从一个指针返回字节型  这里会在初始化的时候进行硬编码 详见 sub main
            Dim nRet As Long
            CopyMemory nRet, ByVal p, 1
            GetPointByte = nRet
    End Function
    
    Public Function CreateIOCP() As Long                                        '创建一个IOCP端口
            CreateIOCP = CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, -1, 0) '这个函数的参数有点复杂 详见 百度 GG  MSDN
    End Function
    
    Public Function BindIOCP(ByVal h As Long, ByVal completKey) As Long         '绑定一个句柄到IOCP h是要绑定的句柄  completKey是完成键
            BindIOCP = CreateIoCompletionPort(h, hIOCP, completKey, 0)
    End Function
    
    Public Function Recv(ByVal s As Long, ByRef pPerData As PerDataStruct) As Long '投递一个WSARecv  参数 s是要投递的socket pPerData是要投递的单IO数据
    
            Dim nRet As Long
    
            Dim tmp As WSABUF
            Dim nBytes As Long
            Dim nFlag As Long
            
            nFlag = 0
            tmp.pBuf = VarPtr(pPerData.buf(0))
            tmp.nLen = MAX_PERBUFLEN
            '根据MSDN wsabuf 可以用临时变量 WSARecv 内部会复杂一份出去
            
            'overlapp结构 清零
            pPerData.ovlap.hEvent = 0
            pPerData.ovlap.Internal = 0
            pPerData.ovlap.InternalHigh = 0
            pPerData.ovlap.Offset = 0
            pPerData.ovlap.OffsetHigh = 0
            
            pPerData.operation = IORecv         '重点  operation是用来识别每次IO是什么操作的重要标志
            
            nRet = WSARecv(s, tmp, 1, nBytes, nFlag, pPerData.ovlap, 0) '参数有点多 详见 百度 GG  MSDN
    
            If nRet = SOCKET_ERROR And Err.LastDllError <> WSA_IO_PENDING Then
                    Recv = -1
            Else
                    Recv = 0
            End If
    
    End Function
    
    Public Function Send(ByVal s As Long, ByRef pPerData As PerDataStruct) As Long '投递一个WSASend  参数 s是要投递的socket pPerData是要投递的单IO数据
    
            Dim nRet As Long
    
            Dim tmp As WSABUF
    
            Dim nBytes As Long
    
            Dim nFlag As Long
            
            nFlag = 0
            tmp.pBuf = VarPtr(pPerData.buf(0))
            tmp.nLen = pPerData.nLen
    
            pPerData.ovlap.hEvent = 0
            pPerData.ovlap.Internal = 0
            pPerData.ovlap.InternalHigh = 0
            pPerData.ovlap.Offset = 0
            pPerData.ovlap.OffsetHigh = 0
            
            pPerData.operation = IOSend   '''''注释同上
            
            nRet = WSASend(s, tmp, 1, nBytes, nFlag, pPerData.ovlap, 0)
            
            If nRet = SOCKET_ERROR And Err.LastDllError <> WSA_IO_PENDING Then
                    Send = -1
            Else
                    Send = 0
            End If
    
    End Function
    
    '独立开一个监听线程  实际情况中可能用不着开一个监听线程 可以直接在IOCP中投递一个AcceptEx 利用IOCP的来接受连接  这里偷懒 直接开一个线程来处理了
    Public Function ListenFunc(ByVal s As Long) As Long
            CreateIExprSrvObj 0, 4, 0
            CoInitialize 0
            
            Dim nRet As Long
    
            Dim nClientIndex As Long
    
            Dim nPerDataIndex As Long
    
            Dim pOverlap As Long
    
            Dim nBytes As Long
    
            Dim nPerIndex As Long
            
            Dim sAddr As sockaddr_in
    
            Dim sAddrLen As Long
    
            Dim ip As String
    
            listen hListenSck, 100
            
            Do While True
            
                    sAddrLen = 16
                    nRet = accept(hListenSck, sAddr, sAddrLen)
                    
                    '/ip = Str(GetPointByte(VarPtr(sAddr.sin_addr))) + "." + Str(GetPointByte(VarPtr(sAddr.sin_addr) + 1)) + "." + Str(GetPointByte(VarPtr(sAddr.sin_addr) + 2)) + "." + Str(GetPointByte(VarPtr(sAddr.sin_addr) + 3))
                    
                    If nRet = SOCKET_ERROR Then
    
                            Exit Do
    
                    End If
                    
                    nClientIndex = NewClient()                              '分配一个内存
                    Clientlist(nClientIndex).ip = sAddr.sin_addr            '保存IP
    
                    Clientlist(nClientIndex).sck = nRet                     '保存 接受的socket
                    
                    '关联到IOCP中  这里我用数组的索引作完成建 当GQCS返回的时候 那里返回的 完成键 就是这里关联的数组索引 通过这数组索引就可以得到client数据 然后进行IO操作
                    CreateIoCompletionPort nRet, hIOCP, nClientIndex, 0
                    
                    
                    nPerDataIndex = NewPerData()                            '分配一个数据
                    
                    
                    '接受链接后 投递一个 WSARecv 等待数据 当收到数据的时候 WSARecv(s, tmp, 1, nBytes, nFlag, pPerData.ovlap, 0) 这里投递的信息以及收到的数据 会通过GQCS就会返回
    
                    nRet = Recv(Clientlist(nClientIndex).sck, PerData(nPerDataIndex))
    
                    If nRet = -1 Then
                            ReleaseClient (nClientIndex)
                            ReleasePerData (nPerDataIndex)
                    End If
    
            Loop
    
            CoUninitialize
    End Function
    
    'IOCP的工作线程 IOCP中最繁忙的就是这里了
    Public Function WorkFunc(ByVal l As Long) As Long
            CreateIExprSrvObj 0, 4, 0
            
            CoInitialize 0
    
            Dim nRet As Long
    
            Dim ComKey As Long       '完成键  是client数组的索引
    
            Dim pOverlap As Long     '一个指针 指向一个overlapped结构 这个结构是WSARecv或者WSASend投递进去的
            
            Dim nBytes As Long       '发送或者接受 处理了多少数据
    
            Dim nPerIndex As Long    '数据索引
    
            Do While True
            
                    '这里参数也很多 详见 百度 GG  MSDN
                    nRet = GetQueuedCompletionStatus(hIOCP, nBytes, ComKey, pOverlap, INFINITE)
                    
                    '我们要得到我们投递的 IO数据信息 详见上面的 PerDataStruct 结构
                    'pOverlap指针 - 4 就是得到 tag成员 tag成员标识 的是数组索引
                    
                    nPerIndex = GetPointInt(pOverlap - 4)
                    
                    If nPerIndex <> -1 Then
                    
                            '得到数组索引我们就可以看到我们的操作结果了 operation是标识我们做的是上面操作 在WSARecv 和WSASend中 填充
                            Select Case PerData(nPerIndex).operation
                    
                                    Case IOSend
                                            nRet = -1
                                            '如果数据长度是0 则说明断开连接了 当然 实际有多种情况 这里只做简单判断
                                            
                                            If nBytes <> 0 Then
                                                    PerData(nPerIndex).nLen = MAX_PERBUFLEN
                                                    nRet = Recv(Clientlist(ComKey).sck, PerData(nPerIndex))
                                                    
                                                    '如果投递失败( 返回-1)  则说明断开连接了  实际有多种情况 这里只做简单判断
                                                    
                                                    InterlockedIncrement SendPackageCount
                                                    InterlockedExchangeAdd SendBytesCount, nBytes
                                        
                                            End If
    
                                            If nRet = -1 Then
                                                    ReleaseClient (ComKey)
                                                    ReleasePerData (nPerIndex)
                                            End If
    
                                    Case IORecv
                                            nRet = -1
                                            
                                            '如果数据长度是0 则说明断开连接了 当然 实际有多种情况 这里只做简单判断
                                            If nBytes <> 0 Then
                                                    PerData(nPerIndex).nLen = nBytes
                                                    nRet = Send(Clientlist(ComKey).sck, PerData(nPerIndex))
                                                    '如果投递失败( 返回-1)  则说明断开连接了  实际有多种情况 这里只做简单判断
                                                    
                                                    InterlockedIncrement RecvPackageCount
                                                    InterlockedExchangeAdd RecvBytesCount, nBytes
                                            End If
    
                                            If nRet = -1 Then
                                                    ReleaseClient (ComKey)
                                                    ReleasePerData (nPerIndex)
                                            End If
    
                            End Select
    
                    End If
            
            Loop '循环 得到下一个IO
    
            CoUninitialize
    End Function
    Public Function TmpGetAddr(ByVal a) As Long
    TmpGetAddr = a
    End Function

  3. #3

    Thread Starter
    PowerPoster
    Join Date
    Jan 2020
    Posts
    3,749

    Re: Iocp Server by vb6

    SocketAPI.bas

    Code:
    Option Explicit
    
    Public Declare Function WSAGetLastError Lib "ws2_32.dll" () As Long
    
    Public Declare Function WSAStartup Lib "ws2_32.dll" (ByVal wVersionRequired As Long, lpWSADATA As WSAData) As Long
    
    Public Declare Function WSACleanup Lib "ws2_32.dll" () As Long
    
    Public Declare Function WSASocketA Lib "ws2_32.dll" (ByVal af As Long, ByVal ntype As Long, ByVal protocol As Long, ByVal lpProtocolInfo As Long, ByVal g As Long, ByVal dwFlags As Long) As Long
    
    Public Declare Function WSASend Lib "ws2_32.dll" (ByVal s As Long, ByRef Buffers As WSABUF, ByVal dwBufferCount As Long, ByRef lpNumberOfBytesSent As Long, ByVal dwFlags As Long, lpOverlapped As OVERLAPPED, ByVal lpCompletionRoutine As Long) As Long
    
    Public Declare Function WSARecv Lib "ws2_32.dll" (ByVal s As Long, ByRef Buffers As WSABUF, ByVal dwBufferCount As Long, ByRef lpNumberOfBytesSent As Long, ByRef dwFlags As Long, lpOverlapped As OVERLAPPED, ByVal lpCompletionRoutine As Long) As Long
    
    Public Declare Function socket Lib "ws2_32.dll" (ByVal af As Long, ByVal s_type As Long, ByVal protocol As Long) As Long
    
    Public Declare Function connect Lib "ws2_32.dll" (ByVal s As Long, ByRef name As sockaddr_in, ByVal namelen As Long) As Long
    
    Public Declare Function bind Lib "ws2_32.dll" (ByVal s As Long, ByRef name As sockaddr_in, ByRef namelen As Long) As Long
    
    Public Declare Function listen Lib "ws2_32.dll" (ByVal s As Long, ByVal backlog As Long) As Long
    
    Public Declare Function accept Lib "ws2_32.dll" (ByVal s As Long, ByRef addr As sockaddr_in, ByRef addrlen As Long) As Long
    
    Public Declare Function ioctlsocket Lib "ws2_32.dll" (ByVal s As Long, ByVal cmd As Long, ByRef argp As Long) As Long
    
    Public Declare Function closesocket Lib "ws2_32.dll" (ByVal s As Long) As Long
    
    ''''''''''''
    Public Declare Function getsockname Lib "ws2_32.dll" (ByVal s As Long, ByRef name As sockaddr_in, ByRef namelen As Long) As Long
    
    Public Declare Function getpeername Lib "ws2_32.dll" (ByVal s As Long, ByRef name As sockaddr_in, ByRef namelen As Long) As Long
    
    Public Declare Function gethostname Lib "ws2_32.dll" (ByVal host_name As String, ByVal namelen As Long) As Long
    
    Public Declare Function gethostbyname Lib "ws2_32.dll" (ByVal host_name As String) As Long
    
    Public Declare Function inet_addr Lib "ws2_32.dll" (ByVal cp As String) As Long
    
    Public Declare Function inet_ntoa Lib "ws2_32.dll" (ByVal inn As Long) As Long
    
    Public Declare Function htons Lib "ws2_32.dll" (ByVal hostshort As Integer) As Integer
    
    Public Declare Function ntohs Lib "ws2_32.dll" (ByVal netshort As Integer) As Integer
    
    Public Declare Function getsockopt Lib "ws2_32.dll" (ByVal s As Long, ByVal level As Long, ByVal optname As Long, optval As Any, optlen As Long) As Long
    
    Public Declare Function setsockopt Lib "ws2_32.dll" (ByVal s As Long, ByVal level As Long, ByVal optname As Long, optval As Any, ByVal optlen As Long) As Long
    
    Public Declare Function gethostbyaddr Lib "ws2_32.dll" (addr As Long, ByVal addr_len As Long, ByVal addr_type As Long) As Long
    
    Public Declare Function lstrlen Lib "kernel32" Alias "lstrlenA" (ByVal lpString As Any) As Long
    
    Public Declare Function lstrcpy Lib "kernel32" Alias "lstrcpyA" (ByVal lpString1 As String, ByVal lpString2 As Long) As Long
    
    Public Type WSABUF
    
            nLen As Long  ' /* the length of the buffer */
            pBuf As Long       '* the pointer to the buffer */
    
    End Type
    
    Public Const SOMAXCONN As Long = 5
    
    Public Enum ProtocolConstants
    
            sckTCPProtocol = 0
            sckUDPProtocol = 1
    
    End Enum
    
    Public Const MSG_PEEK  As Long = &H2
    
    Public Const SOCKET_ERROR   As Integer = -1
    
    Public Const INVALID_SOCKET As Integer = -1
    
    Public Const INADDR_NONE As Long = &HFFFF
    
    Public Const WSADESCRIPTION_LEN As Integer = 257
    
    Public Const WSASYS_STATUS_LEN  As Integer = 129
    
    Public Enum WinsockVersion
    
            SOCKET_VERSION_11 = &H101
            SOCKET_VERSION_22 = &H202
    
    End Enum
    
    Public Const MAXGETHOSTSTRUCT = 1024
    
    Public Const AF_INET        As Long = 2
    
    Public Const SOCK_STREAM    As Long = 1
    
    Public Const SOCK_DGRAM     As Long = 2
    
    Public Const IPPROTO_TCP    As Long = 6
    
    Public Const IPPROTO_UDP    As Long = 17
    
    Public Const IPPROTO_IP    As Long = 0
    
    Public Const WSA_FLAG_OVERLAPPED     As Long = &H1
    
    Public Const OFFSET_2 = 65536
    
    Public Const MAXINT_2 = 32767
    
    Public Const LOCAL_HOST_BUFF As Integer = 256
    
    Public Const SOL_SOCKET         As Long = 65535
    
    Public Const SO_SNDBUF          As Long = &H1001&
    
    Public Const SO_RCVBUF          As Long = &H1002&
    
    Public Const SO_MAX_MSG_SIZE    As Long = &H2003
    
    Public Const SO_BROADCAST       As Long = &H20
    
    Public Const FIONREAD           As Long = &H4004667F
    
    '==============================================================================
    'ERROR CODES
    '==============================================================================
    Public Const WSA_IO_PENDING     As Long = 997
    
    Public Const WSABASEERR         As Long = 10000
    
    Public Const WSAEINTR           As Long = (WSABASEERR + 4)
    
    Public Const WSAEACCES          As Long = (WSABASEERR + 13)
    
    Public Const WSAEFAULT          As Long = (WSABASEERR + 14)
    
    Public Const WSAEINVAL          As Long = (WSABASEERR + 22)
    
    Public Const WSAEMFILE          As Long = (WSABASEERR + 24)
    
    Public Const WSAEWOULDBLOCK     As Long = (WSABASEERR + 35)
    
    Public Const WSAEINPROGRESS     As Long = (WSABASEERR + 36)
    
    Public Const WSAEALREADY        As Long = (WSABASEERR + 37)
    
    Public Const WSAENOTSOCK        As Long = (WSABASEERR + 38)
    
    Public Const WSAEDESTADDRREQ    As Long = (WSABASEERR + 39)
    
    Public Const WSAEMSGSIZE        As Long = (WSABASEERR + 40)
    
    Public Const WSAEPROTOTYPE      As Long = (WSABASEERR + 41)
    
    Public Const WSAENOPROTOOPT     As Long = (WSABASEERR + 42)
    
    Public Const WSAEPROTONOSUPPORT As Long = (WSABASEERR + 43)
    
    Public Const WSAESOCKTNOSUPPORT As Long = (WSABASEERR + 44)
    
    Public Const WSAEOPNOTSUPP      As Long = (WSABASEERR + 45)
    
    Public Const WSAEPFNOSUPPORT    As Long = (WSABASEERR + 46)
    
    Public Const WSAEAFNOSUPPORT    As Long = (WSABASEERR + 47)
    
    Public Const WSAEADDRINUSE      As Long = (WSABASEERR + 48)
    
    Public Const WSAEADDRNOTAVAIL   As Long = (WSABASEERR + 49)
    
    Public Const WSAENETDOWN        As Long = (WSABASEERR + 50)
    
    Public Const WSAENETUNREACH     As Long = (WSABASEERR + 51)
    
    Public Const WSAENETRESET       As Long = (WSABASEERR + 52)
    
    Public Const WSAECONNABORTED    As Long = (WSABASEERR + 53)
    
    Public Const WSAECONNRESET      As Long = (WSABASEERR + 54)
    
    Public Const WSAENOBUFS         As Long = (WSABASEERR + 55)
    
    Public Const WSAEISCONN         As Long = (WSABASEERR + 56)
    
    Public Const WSAENOTCONN        As Long = (WSABASEERR + 57)
    
    Public Const WSAESHUTDOWN       As Long = (WSABASEERR + 58)
    
    Public Const WSAETIMEDOUT       As Long = (WSABASEERR + 60)
    
    Public Const WSAEHOSTUNREACH    As Long = (WSABASEERR + 65)
    
    Public Const WSAECONNREFUSED    As Long = (WSABASEERR + 61)
    
    Public Const WSAEPROCLIM        As Long = (WSABASEERR + 67)
    
    Public Const WSASYSNOTREADY     As Long = (WSABASEERR + 91)
    
    Public Const WSAVERNOTSUPPORTED As Long = (WSABASEERR + 92)
    
    Public Const WSANOTINITIALISED  As Long = (WSABASEERR + 93)
    
    Public Const WSAHOST_NOT_FOUND  As Long = (WSABASEERR + 1001)
    
    Public Const WSATRY_AGAIN       As Long = (WSABASEERR + 1002)
    
    Public Const WSANO_RECOVERY     As Long = (WSABASEERR + 1003)
    
    Public Const WSANO_DATA         As Long = (WSABASEERR + 1004)
    
    '==============================================================================
    'WINSOCK CONTROL ERROR CODES
    '==============================================================================
    
    Public Const sckOutOfMemory = 7
    
    Public Const sckBadState = 40006
    
    Public Const sckInvalidArg = 40014
    
    Public Const sckUnsupported = 40018
    
    Public Const sckInvalidOp = 40020
    
    '==============================================================================
    'STRUCTURES
    '==============================================================================
    
    Public Type WSAData
    
            wVersion       As Integer
            wHighVersion   As Integer
            szDescription  As String * WSADESCRIPTION_LEN
            szSystemStatus As String * WSASYS_STATUS_LEN
            iMaxSockets    As Integer
            iMaxUdpDg      As Integer
            lpVendorInfo   As Long
    
    End Type
    
    Public Type HOSTENT
    
            hName     As Long
            hAliases  As Long
            hAddrType As Integer
            hLength   As Integer
            hAddrList As Long
    
    End Type
    
    Public Type sockaddr_in
    
            sin_family       As Integer
            sin_port         As Integer
            sin_addr         As Long
            sin_zero(1 To 8) As Byte
    
    End Type
    
    Public Function BindServerSocket(ByVal s As Long, ByVal port As Integer, ByVal ip As String) As Boolean
            
            Dim nRet As Long
    
            Dim sAddr As sockaddr_in
    
            sAddr.sin_family = AF_INET
    
            If ip <> "" Then
                    sAddr.sin_addr = inet_addr(ip)
            Else
                    sAddr.sin_addr = 0
            End If
    
            sAddr.sin_port = htons(port)
            nRet = bind(hListenSck, sAddr, LenB(sAddr))
            
            If nRet = SOCKET_ERROR Then
                    BindServerSocket = False
            Else
                    BindServerSocket = True
            End If
     
    End Function
    
    Public Function CreateSocket() As Long
            CreateSocket = WSASocketA(AF_INET, SOCK_STREAM, IPPROTO_IP, 0, 0, WSA_FLAG_OVERLAPPED)
    End Function
    
    Public Function Initsockdll() As Boolean
    
            Dim tmp As WSAData
    
            Dim nRet As Long
    
            nRet = WSAStartup(SOCKET_VERSION_22, tmp)
    
            If nRet <> 0 Then
                    Initsockdll = False
            Else
                    Initsockdll = True
            End If
    
    End Function
    
    Public Sub Releasesockdll()
            Call WSACleanup
    End Sub
    
    Public Function GetErrorDescription(ByVal lngErrorCode As Long) As String
    
            Select Case lngErrorCode
    
                    Case WSAEACCES
                            GetErrorDescription = "Permission denied."
    
                    Case WSAEADDRINUSE
                            GetErrorDescription = "Address already in use."
    
                    Case WSAEADDRNOTAVAIL
                            GetErrorDescription = "Cannot assign requested address."
    
                    Case WSAEAFNOSUPPORT
                            GetErrorDescription = "Address family not supported by protocol family."
    
                    Case WSAEALREADY
                            GetErrorDescription = "Operation already in progress."
    
                    Case WSAECONNABORTED
                            GetErrorDescription = "Software caused connection abort."
    
                    Case WSAECONNREFUSED
                            GetErrorDescription = "Connection refused."
    
                    Case WSAECONNRESET
                            GetErrorDescription = "Connection reset by peer."
    
                    Case WSAEDESTADDRREQ
                            GetErrorDescription = "Destination address required."
    
                    Case WSAEFAULT
                            GetErrorDescription = "Bad address."
    
                    Case WSAEHOSTUNREACH
                            GetErrorDescription = "No route to host."
    
                    Case WSAEINPROGRESS
                            GetErrorDescription = "Operation now in progress."
    
                    Case WSAEINTR
                            GetErrorDescription = "Interrupted function call."
    
                    Case WSAEINVAL
                            GetErrorDescription = "Invalid argument."
    
                    Case WSAEISCONN
                            GetErrorDescription = "Socket is already connected."
    
                    Case WSAEMFILE
                            GetErrorDescription = "Too many open files."
    
                    Case WSAEMSGSIZE
                            GetErrorDescription = "Message too long."
    
                    Case WSAENETDOWN
                            GetErrorDescription = "Network is down."
    
                    Case WSAENETRESET
                            GetErrorDescription = "Network dropped connection on reset."
    
                    Case WSAENETUNREACH
                            GetErrorDescription = "Network is unreachable."
    
                    Case WSAENOBUFS
                            GetErrorDescription = "No buffer space available."
    
                    Case WSAENOPROTOOPT
                            GetErrorDescription = "Bad protocol option."
    
                    Case WSAENOTCONN
                            GetErrorDescription = "Socket is not connected."
    
                    Case WSAENOTSOCK
                            GetErrorDescription = "Socket operation on nonsocket."
    
                    Case WSAEOPNOTSUPP
                            GetErrorDescription = "Operation not supported."
    
                    Case WSAEPFNOSUPPORT
                            GetErrorDescription = "Protocol family not supported."
    
                    Case WSAEPROCLIM
                            GetErrorDescription = "Too many processes."
    
                    Case WSAEPROTONOSUPPORT
                            GetErrorDescription = "Protocol not supported."
    
                    Case WSAEPROTOTYPE
                            GetErrorDescription = "Protocol wrong type for socket."
    
                    Case WSAESHUTDOWN
                            GetErrorDescription = "Cannot send after socket shutdown."
    
                    Case WSAESOCKTNOSUPPORT
                            GetErrorDescription = "Socket type not supported."
    
                    Case WSAETIMEDOUT
                            GetErrorDescription = "Connection timed out."
    
                    Case WSAEWOULDBLOCK
                            GetErrorDescription = "Resource temporarily unavailable."
    
                    Case WSAHOST_NOT_FOUND
                            GetErrorDescription = "Host not found."
    
                    Case WSANOTINITIALISED
                            GetErrorDescription = "Successful WSAStartup not yet performed."
    
                    Case WSANO_DATA
                            GetErrorDescription = "Valid name, no data record of requested type."
    
                    Case WSANO_RECOVERY
                            GetErrorDescription = "This is a nonrecoverable error."
    
                    Case WSASYSNOTREADY
                            GetErrorDescription = "Network subsystem is unavailable."
    
                    Case WSATRY_AGAIN
                            GetErrorDescription = "Nonauthoritative host not found."
    
                    Case WSAVERNOTSUPPORTED
                            GetErrorDescription = "Winsock.dll version out of range."
    
                    Case Else
                            GetErrorDescription = "Unknown error."
            End Select
    
    End Function
    ThreadMod.bas
    Code:
    Option Explicit
    
    Public Declare Function CreateThread Lib "kernel32" (ByVal lpThreadA As Long, ByVal dwStackSize As Long, ByVal lpStartAddress As Long, ByVal lpParameter As Long, ByVal dwCreationFlags As Long, lpThreadId As Long) As Long
    
    Public Declare Function WriteProcessMemory Lib "kernel32" (ByVal hProcess As Long, lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
    
    Public Declare Function TerminateThread Lib "kernel32" (ByVal hThread As Long, ByVal dwExitCode As Long) As Long
    
    Public Declare Function CoInitialize Lib "ole32.dll" (ByVal pvReserved As Long) As Long
    
    Public Declare Sub CoUninitialize Lib "ole32.dll" ()
    
    Public Declare Function CreateIExprSrvObj Lib "msvbvm60.dll" (ByVal p1_0 As Long, ByVal p2_4 As Long, ByVal p3_0 As Long) As Long

  4. #4
    Frenzied Member
    Join Date
    Aug 2020
    Posts
    1,447

    Re: Iocp Server by vb6

    In my opinion, it makes no sense to post some Chinese websites links on an English-only forum.

  5. #5

    Thread Starter
    PowerPoster
    Join Date
    Jan 2020
    Posts
    3,749

    Re: Iocp Server by vb6

    Quote Originally Posted by SearchingDataOnly View Post
    In my opinion, it makes no sense to post some Chinese websites links on an English-only forum.
    Because the source code comes from that website and is not original by me,so i attach it as a comment.
    Last edited by xiaoyao; Mar 20th, 2023 at 05:38 AM.

  6. #6
    Frenzied Member
    Join Date
    Dec 2012
    Posts
    1,477

    Re: Iocp Server by vb6

    Like yourself, I have been quite interested in enabling a server to be able to service multiple connections efficiently. My own SimpleServer is adequate, but it has limitations when trying to service multiple connections. With multi-core CPUs being very common these days, using multiple threads only makes sense. Because managing multiple threads is not easily handled by VB6, I have pretty much steered clear of it in the past, but maybe it is time to take another look at it.

    One problem that surfaced very quickly was that when the program was exited, the listening socket was left open. This caused a "Bind" error the next time the program was attempted to be run. Adding "Releasesockdll" to the form unload solved that.

    J.A. Coutts

  7. #7

    Thread Starter
    PowerPoster
    Join Date
    Jan 2020
    Posts
    3,749

    Re: Iocp Server by vb6

    Yes, if you multithread a URL task with hundreds of thousands of lines in a text file, 10 threads open 10 URLs in different locations. Uch as 102, 105, and 106. If they are closed carelessly or manually, these records need to be reprocessed next time. These are some of the troublesome things about multithreading.

  8. #8
    Frenzied Member
    Join Date
    Dec 2012
    Posts
    1,477

    Re: Iocp Server by vb6

    When attempting to transfer a 66,956 byte file to the server, it stops after 29,725 bytes. I believe this is caused by the client closing the connection after sending the data. A socket connection normally enters a CLOSE_WAIT state when the client closes the connection, but obviously the threaded version does not. If I delay the closing of the client connection, the full 66,956 bytes gets received.

    How do I address this issue?

    J.A. Coutts

  9. #9

    Thread Starter
    PowerPoster
    Join Date
    Jan 2020
    Posts
    3,749

    Re: Iocp Server by vb6

    Just like winsock control, there should be a way to know whether the transmission is successful or not

  10. #10
    Frenzied Member
    Join Date
    Dec 2012
    Posts
    1,477

    Re: Iocp Server by vb6

    Quote Originally Posted by xiaoyao View Post
    Just like winsock control, there should be a way to know whether the transmission is successful or not
    By using a Packet Viewer, I found that this program was sending the same thing back to the client. The reason the program stopped receiving was that the client was not recovering any of those packets, and when it closed the socket, the server detected that and stopped receiving. It became very obvious that the intention of this program was to stress test IOCP, rather than actually sending and recovering data.

    My attempts to fix the program have not met with success. When I remove the "Send" instruction from the WorkFunc routine, the program drops the last record, and I have not been able to figure out why.

    J.A. Coutts

  11. #11

    Thread Starter
    PowerPoster
    Join Date
    Jan 2020
    Posts
    3,749

    Re: Iocp Server by vb6

    maybe yor are right.
    if you want to send data and receive,will not lost data,you need add some code for check ,like
    Code:
    Private Sub Winsock1_SendComplete()
    
    End Sub

  12. #12
    Frenzied Member
    Join Date
    Dec 2012
    Posts
    1,477

    Re: Iocp Server by vb6

    Quote Originally Posted by xiaoyao View Post
    maybe yor are right.
    if you want to send data and receive,will not lost data,you need add some code for check ,like
    Code:
    Private Sub Winsock1_SendComplete()
    
    End Sub
    The data is being sent. the last record is just not being recovered by the server, and it is difficult to figure out what the worker function is doing. It is entered and exited multiple times.

    J.A. Coutts

  13. #13
    Frenzied Member
    Join Date
    Dec 2012
    Posts
    1,477

    Re: Iocp Server by vb6

    Most of the examples I could find were in C++, and virtually all of them were what they called "Echo Servers". So I was left with the good old trial & error method. Removing the "Send" from "Case IORecv" did not work. Setting the buffer length to 0 also did not work. Setting the buffer length to 1 sort of worked. However, an additional record consisting of the last record and part of the second last record were received. Using a buffer length of 1, and clearing the buffer seemed to produce a more accurate result
    Code:
    Case IORecv
        nRet = -1
        If nBytes <> 0 Then
            PerData(nPerIndex).nLen = nBytes
        Debug.Print Utf8ToStr(PerData(nPerIndex).buf)
            Erase PerData(nPerIndex).buf
            PerData(nPerIndex).nLen = 1
            nRet = Send(Clientlist(ComKey).sck, PerData(nPerIndex))
            'There are actually many situations. Here we only make a simple judgment.
            InterlockedIncrement RecvPackageCount
            InterlockedExchangeAdd RecvBytesCount, nBytes
        End If
        If nRet = -1 Then
            ReleaseClient (ComKey)
            ReleasePerData (nPerIndex)
        End If
    Why on earth would it need an echo record to work?

    J.A. Coutts

  14. #14
    Frenzied Member
    Join Date
    Dec 2012
    Posts
    1,477

    Re: Iocp Server by vb6

    After a lot of searching, I finally found a decent explanation:
    https://www.winsocketdotnetworkprogr...omethod5j.html
    Code:
        'Wait for I/O to complete on any socket associated with the completion port
        nRet = GetQueuedCompletionStatus(hIOCP, nBytes, ComKey, pOverlap, INFINITE)
        'Get array index
        nPerIndex = GetPointInt(pOverlap - 4)
        If nPerIndex <> -1 Then
            'Service the completed I/O request. You can determine which I/O request has just
            'completed by looking at the OperationType field contained in the per-I/O operation data.
            Select Case PerData(nPerIndex).operation
                Case IORecv
                    If nBytes = 0 Then
                        'A zero BytesTransferred indicates that the socket has been closed by the peer, so
                        'you should close the socket. Note: Per-handle data was used to reference the
                        'socket associated with the I/O operation.
                        nRet = -1
                    Else
                        PerData(nPerIndex).nLen = nBytes
                        Dbgprint Utf8ToStr(PerData(nPerIndex).buf)
                        nRet = Recv(Clientlist(ComKey).sck, PerData(nPerIndex))
                        InterlockedIncrement RecvPackageCount
                        InterlockedExchangeAdd RecvBytesCount, nBytes
                    End If
            End Select
            If nRet = -1 Then  'The sender disconnected.
                ReleaseClient (ComKey)
                ReleasePerData (nPerIndex)
            End If
        End If
    To say that it simplified the process would be a gross overstatement, but at least it got me on the right track. The posting of a send or receive simply appears to enable the thread to react to the actual send or receive.

    J.A Coutts

  15. #15

    Thread Starter
    PowerPoster
    Join Date
    Jan 2020
    Posts
    3,749

    Re: Iocp Server by vb6

    Programmers are indeed very lonely because what you say is difficult for others to understand.
    This source code was reposted by me, and I am not sure what its ultimate purpose is and whether it can be used in commercial engineering.

  16. #16
    Hyperactive Member
    Join Date
    Jun 2016
    Location
    EspaƱa
    Posts
    508

    Re: Iocp Server by vb6


  17. #17
    Addicted Member
    Join Date
    May 2012
    Location
    42.787034,-81.176367
    Posts
    133

    Re: Iocp Server by vb6

    Go back in time to look at the site, when it was up...

    https://web.archive.org/web/20230331...ww.vbgood.com/

    Joe

  18. #18

    Thread Starter
    PowerPoster
    Join Date
    Jan 2020
    Posts
    3,749

    Re: Iocp Server by vb6

    Pudn is another research life-saving path under the business model of CSDN, where I often lose contact with GitHub in China. My ideas 1, 2, and 3, which I am about to modify, are all inspired by the initial code of Pudn. I haven't written any new research code for more than half a year, and I am so sad to find that the website is gone. Other floors have also written about intellectual property issues, and everyone has opened them up in various ways with the purpose of sharing. Domestic GitHub is often affected by domain names and cannot enter, so there will be some movement on Pudn. This is understandable, and it is always more emotional than the fee code transferred on CSdn. The excellent search function of Pudn has really helped me a lot. When I saw the first floor, it seemed like the webmaster was speaking, and it was a pity to close the website. Today, through searching, I found that many local websites have been stopped. We need a good online environment, and we also hope everyone can do their best, so as not to let kindness chill their hearts

  19. #19
    Frenzied Member
    Join Date
    Dec 2012
    Posts
    1,477

    Re: Iocp Server by vb6

    I finally figured out how to start a Send function. The Recv function is triggered by the incoming packet, but I was having difficulty in starting the Send.
    Code:
    Private Sub Command1_Click()
        Dim bMsg() As Byte
        Dim bLen As Long
        Dim pPerData(1) As PerDataStruct
        bLen = 12
        bMsg = StrToUtf8("Hello World!")
        pPerData(1).buf(0) = 1
        pPerData(1).buf(1) = 3
        pPerData(1).buf(2) = 3
        pPerData(1).buf(4) = bLen
        CopyMemory pPerData(1).buf(5), bMsg(0), bLen
        pPerData(1).nLen = bLen + 5
        bLen = Send(Clientlist(1).sck, pPerData(1))
    End Sub
    In this case, the client required a 5 byte header. The client establishes the connection, and the server must then be instructed to send the first packet. Once the first packet is sent, it will carry on with the rest of the record using the Worker thread.

    Which brings up another question. Winsock 1 used to default to a packet size of 4K bytes. In this case the term "packet" is not being used to describe the network packet size (MTU size), but rather the packet returned by Winsock (buffer size). Winsock 2 appears to default to 64K. This leaves me in a quandary as to what the best size is for the IOCP buffer. 1K seems a bit low, unless the small size is more efficient for a large number of connections.

    J.A. Coutts

  20. #20
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Location
    Sofia, Bulgaria
    Posts
    5,163

    Re: Iocp Server by vb6

    There is no best size on TCP/IP layer because MTU depends on underlying (think ethernet) physical layer which might use jumbo packets or SPF+ optical cables (instead of copper) which have different defaults.

  21. #21
    Frenzied Member
    Join Date
    Dec 2012
    Posts
    1,477

    Re: Iocp Server by vb6

    Quote Originally Posted by wqweto View Post
    There is no best size on TCP/IP layer because MTU depends on underlying (think ethernet) physical layer which might use jumbo packets or SPF+ optical cables (instead of copper) which have different defaults.
    I have long said that Ethernet MTU size is about 1500 bytes. In actual fact it is 28 bytes less, or 1472 bytes, which accounts for the overhead that accompanies each MTU packet. You can test your own network router by issuing the following command from the Command Prompt:
    ping 192.168.x.x -f -l 1472
    with the address being that of the router. Adjusting the last number will show you where the limit is. The overhead data is used by the router to make sure the packets are reassembled in the correct order after fragmentation. Packets that are fragmented are slightly slower than non-fragmented packets, but these days that is not much of an issue.

    But MTU size has little to do with what Winsock reports back to the operating system. As long as the data comes in at a sufficient speed, Winsock will report back once its buffer is full, or after a timeout. With Winsock 1, the default is 4,096 bytes (4K). With Winsock 2, the default is 65,536 bytes (64K). I do not know if Winsock is capable of reassembling packets should they comes in out of order. I suspect that it is not capable, as some IOCP writeups suggest that it could be a problem. Those same writeups also suggest that buffer size should be adjusted for the intended application, which is the reason for my question. My intended application is file transfer.

    J.A. Coutts
    Last edited by couttsj; Apr 12th, 2023 at 01:08 PM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width