Author | Message | Time |
---|---|---|
vector | I'm trying to polish my server so it can handle multiple sockets flawlessly. Say three sockets are connected. When socket 2 leaves, I want to be able to re-use socket 2. When 1 leaves, I want to re-use 1, etc. I keep trying so and get problems. I've been trying again and again to handle sockets perfectly. Please note that I'm using two sockets. A listening socket, and a control array. Can you post an example of the proper way of handling sockets? (the Winsock_ConnectionRequest Sub is all I need) | October 28, 2008, 3:42 AM |
Yegg | Couldn't they all simply operate on their own thread? Store them in an array as you are already doing. If they are all on their own thread, you can have a function running within each thread that does whatever task whenever the socket loses its connection. Should be pretty simple. | October 28, 2008, 4:47 AM |
Barabajagal | [code]Dim I As Integer For I = 0 To 99 If Winsock(I).State = 0 Then Winsock(I).Accept requestID Exit For End If Next I[/code] Just make sure to close the socket when disconnected. | October 28, 2008, 4:56 AM |
vector | Thanks Andy. I wish IsObject() would return False if the particular array element wasn't loaded, but it returns true.... | October 29, 2008, 10:13 PM |
Barabajagal | Object arrays automatically load all the elements... I think? | October 29, 2008, 11:40 PM |
Ringo | [quote author=vector link=topic=17697.msg180164#msg180164 date=1225318421] I wish IsObject() would return False if the particular array element wasn't loaded, but it returns true.... [/quote] Theres probly a few ways around that, but iirc, this will do the job: IsLoaded = (VarType(Control(X))=vblong) | October 29, 2008, 11:46 PM |
Barabajagal | I know you can do If Not Ary() Then to detect if an array hasn't been initialized, but I don't think individual elements of arrays work like that... | October 30, 2008, 12:39 AM |
l2k-Shadow | [code] Private Sub Form_Load() Dim i As Integer 'Load Winsock1(1) For i = 0 To 1 If IsLoaded(Winsock1(i)) Then MsgBox i & " Is Loaded!" Next i End Sub Public Function IsLoaded(ByVal W As Winsock) As Boolean If VarType(W) <> vbObject Then IsLoaded = True End Function [/code] enjoy | October 30, 2008, 12:49 AM |
vector | Interesting. I took Andy's advice, and it looks nicely: [code] Private Sub sckListen_ConnectionRequest(ByVal requestID As Long) Dim i As Integer For i = 0 To sckRecv.Count If i = sckRecv.Count Then Load sckRecv(i) sckRecv(i).Accept requestID Exit Sub Else If sckRecv(i).State = sckClosed Then sckRecv(i).Accept requestID Exit Sub End If End If Next End Sub [/code] But the wird thing is, when a client leaves, the sckRecv_Close() sub seems to be calling more than once, and the clients seem to be acting up. [IMG]http://i52.photobucket.com/albums/g38/dj_dances/weird-1.jpg[/img] Quite strange. Do you know anything about this? | November 3, 2008, 9:07 PM |
Barabajagal | Let's see your close error. And next time, run it from the IDE so you find out where the error is... | November 3, 2008, 10:02 PM |
Ringo | id persionaly do somthing like this (dunno if this helps you at all) create module called modWinsock.bas create a module called modClient.bas create a class called clsClient.cls modwinsock.bas would be used to managed an array of winsocks, across the whole project. modclient.bas would be used to manage an array of client class's clsclient.cls would be used to manage a clients connection and what not. then in you're form code: [code] Public WithEvents sckServer As MSWinsockLib.Winsock Private Sub Form_Load() Dim i As Integer modWinsock.hSocketCount = -1 modClient.hClientCount = -1 i = modWinsock.GetFreeSocket(Me) Set sckServer = modWinsock.hSocket(i) sckServer.Close sckServer.Bind 2392, sckServer.LocalIP sckServer.Listen End Sub Private Sub sckServer_ConnectionRequest(ByVal requestID As Long) Dim i As Integer 'socket index Dim i2 As Integer 'client index i = modWinsock.GetFreeSocket(Me) i2 = modClient.GetFreeClient() modClient.hClient(i2).sckIndex = i Set modClient.hClient(i2).sckRecv = modWinsock.hSocket(i) Call modClient.hClient(i2).Accept(requestID) End Sub [/code] In the modClient.bas code: [code] Public hClient() As clsClient Public hClientInUse() As Boolean Public hClientCount As Integer Public Function GetFreeClient() As Integer Dim i As Integer For i = 0 To hClientCount If (hClientInUse(i) = False) Then hClientInUse(i) = True GetFreeClient = i Exit Function End If Next i hClientCount = hClientCount + 1 i = hClientCount ReDim Preserve hClientInUse(i) hClientInUse(i) = True ReDim Preserve hClient(i) Set hClient(i) = New clsClient hClient(i).clsIndex = i GetFreeClient = i End Function Public Sub ReleaseClient(ByVal i As Integer) If (i < 0) Or (i > hClientCount) Then Exit Sub Set hClient(i).sckRecv = Nothing Call modWinsock.ReleaseWinsock(hClient.sckIndex) hClient(i).sckIndex = -1 hClientInUse(i) = False End Sub [/code] in the modWinsock.bas code: [code] Public hSocket() As MSWinsockLib.Winsock Public hSocketInUse() As Boolean Public hSocketCount As Integer Public Function GetFreeSocket(ByRef F As VB.Form) As Integer Dim i As Integer For i = 0 To hSocketCount If (hSocketInUse(i) = False) Then hSocketInUse(i) = True GetFreeSocket = i Exit Function End If Next i hSocketCount = hSocketCount + 1 i = hSocketCount ReDim Preserve hSocketInUse(i) hSocketInUse(i) = True ReDim Preserve hSocket(i) Set hSocket(i) = F.Controls.Add("MSWinsock.Winsock", "Winsock" & i) GetFreeSocket = i End Function Public Sub ReleaseSocket(ByVal i As Integer) If (i < 0) Or (i > hSocketCount) Then Exit Sub If hSocketInUse(i) Then hSocketInUse(i) = False hSocket(i).Close End If End Sub [/code] and in the clsClient.cls code: [code] Public WithEvents sckRecv As MSWinsockLib.Winsock Public clsIndex As Integer Public sckIndex As Integer Public Sub Accept(ByVal requestID As Integer) sckRecv.Close sckRecv.Accept requestID End Sub Private Sub sckRecv_Close() Call modClient.ReleaseClient(clsIndex) End Sub Private Sub sckRecv_Error(ByVal Number As Integer, _ Description As String, _ ByVal Scode As Long, _ ByVal Source As String, _ ByVal HelpFile As String, _ ByVal HelpContext As Long, _ CancelDisplay As Boolean) Call modClient.ReleaseClient(clsIndex) End Sub [/code] That way, you can manage many types of client's/class's, all from the same winsock array. For example, you could have a clsFTP.cls client class, that could also get an avalible socket index, from the winsock array. 1 array of winsocks, multiple uses. But thats just me :p Dunno if that helps you, or puts an idea in your head or not. | November 4, 2008, 5:13 AM |
vector | In my sckRecv_Close() sub, I have a feeling that this piece of code: [code] If Index = sckRecv.Count Then Unload sckRecv(Index) [/code] Was for some reason causing the program to re-call the Close() sub, then it happens again, and again. | November 4, 2008, 8:23 PM |
Barabajagal | ...Why are you unloading the socket entirely like that? Are these actual Winsock objects? | November 4, 2008, 8:26 PM |
vector | Yes. Well, it's a control array actually. I load the socket if its last socket in the array. Should I not unload it? | November 4, 2008, 11:57 PM |
Barabajagal | I don't think Winsock likes dynamic arrays like that... | November 5, 2008, 12:10 AM |
vector | I feel like an idiot. On the client, when the form terminated, it would call sckSend.Close, and on the server side, when the socket quits, the close() sub was actually executing twice. I took that line from the client out, and it does just what its supposed to do normally. | November 5, 2008, 7:46 PM |
TheMinistered | search pscode.com for "david Fritts" you'll find really good sample project on how to do this | November 20, 2008, 7:37 PM |