-
May 7th, 2008, 09:29 AM
#1
Thread Starter
Member
Winsock 10048 error [RESOLVED]
Hi All,
[RESOLVED: Problem was that I had another winsock control already listening on the same port numbers! Silly me!]
Firstly I apologise for the long post. I just need to get this sorted. I've been searching all night and can't seem to find an answer. I have a winsock control array on my server form, and a winsock control on my client form.
Ive written a procedure to gather all the data so i don't miss anything coming through the GetData buffer, and all seems to work well I can get data from A-B without loss, and reliably.
Until I close my client, and attempt to open and reconnect (very important to be able to do this quickly) My searching keeps bringing me back here -> http://support.microsoft.com/kb/q173619/
my code is lengthy, with all sort of junk in between, but the general settings are:
server: sckServ
.RemotePort = 4411
.LocalPort = 4511
.Listen
client: sckClient
.RemotePort = 4511
.LocalPort = 0
.Connect
this all works fine and is no problems except for when I try to reconnect I get the dreaded address in use error. MS tells me to set localport as 0.. so I change my sckServ.LocalPort to 0, no longer connects my client throws a state of '6' then shortly after switches to state '9'.. i.e doesn't connect at all. Admittably the error is no longer there.. but my app is not very usable.
I understand the workings of the TCP stack enough to know it will keep a port mapped to an app, unless its closed properly. I'm using the standard .Close method of the winsock control.. should this supplemented with anything else?
Bear in mind that at the moment this is only dealing with one of the sckServ in an array (i haven't got far enough to try that out yet), and I want to use a specific port-set so I can configure port forwding on my router and use this app from work.
A couple of suggestions that I have tried include:
http://www.vbforums.com/showthread.p...=10048+winsock
http://www.vbforums.com/showthread.p...=10048+winsock <- the API I haven't tried but i am in the process of working through it with a sample app im making specifically for this error. If anyone has tried that I'd love to know how you got on with it.
Thanks in advance for any replies, advice, suggestions etc.. I'm really stumped on this one.
Tim.
Last edited by emtark; May 8th, 2008 at 06:45 AM.
Tim.
-
May 7th, 2008, 10:36 AM
#2
Re: Winsock 10048 error
You are really over-complicating the issue with your lengthy post.
Error 10048 means Address already in use.
You are trying to open a connection on a socket that is already in use.
Make sure you always close your socket(s) in the Socket_Close Event
If a client disconnects from the server then the server needs to close the server socket that was used for that client. The client already closed his socket.
If the server disconnects the client (closes his socket) then you do the same thing and close your server socket for that client.
Make sure your are keeping accurate account of the Indexes of the sockets.
Last edited by jmsrickland; May 7th, 2008 at 10:42 AM.
-
May 7th, 2008, 10:51 AM
#3
Re: Winsock 10048 error
You also don't need the RemotePort set on the Server. The RemotePort on the Client connects to the LocalPort of the Server. All other Ports should either be left to default or set to zero.
-
May 7th, 2008, 11:50 AM
#4
Re: Winsock 10048 error
I would agree with Doogle. Set the localport of the server to zero.
server: sckServ
.LocalPort = 0
NOTE: Make sure you install SP6 in your VB.
-
May 7th, 2008, 12:38 PM
#5
Re: Winsock 10048 error
Originally Posted by zynder
I would agree with Doogle. Set the localport of the server to zero.
server: sckServ
.LocalPort = 0
NOTE: Make sure you install SP6 in your VB.
You are agreeing with Doogle on something he didn't say. You don't set the server's localport to 0 because you need it set to some value that the clients can connect to; not sero.
-
May 7th, 2008, 03:27 PM
#6
Re: Winsock 10048 error
That will fix it. It will pick a random port when it is set to zero.
For more info check this out.
http://support.microsoft.com/kb/173619
-
May 7th, 2008, 03:47 PM
#7
Re: Winsock 10048 error
Originally Posted by zynder
That will fix it. It will pick a random port when it is set to zero.
OK, so how does the client know what port number to connect to then if the server port number is a random number?
-
May 7th, 2008, 05:03 PM
#8
-
May 7th, 2008, 07:15 PM
#9
Re: Winsock 10048 error
See Post#3
Don't know to whom this was directed to.
Post #3:
You also don't need the RemotePort set on the Server. The RemotePort on the Client connects to the LocalPort of the Server. All other Ports should either be left to default or set to zero.
You also don't need the RemotePort set on the Server
That's a given.
The RemotePort on the Client connects to the LocalPort of the Server
Which implies that the client must know ahead of time what the LocalPort number of the server is in order to connect to it. But, according to Zynder if you set the server's LocalPort to zero Winsock will generate a port number for you but the client has no way to know what that random number is. Am I correct or am I not?
-
May 7th, 2008, 08:17 PM
#10
Re: Winsock 10048 error
jmsrickland is right...
LocalPort is for server...server doesn't use RemotePort.
RemotePort is for client. This is needs to be the same as the server's LocalPort for it to connect.
Windows will handle the RemotePort of the server automatically, and the LocalPort of the client automatically when a connection is made, so you don't need to set those properties at all.
Code:
With sckServer
.Close
.LocalPort = 1234
.Listen
End With
With sckClient
.Close
.RemoteHost = "123.123.123.123"
.RemotePort = 1234
.Connect
End With
-
May 7th, 2008, 08:44 PM
#11
Re: Winsock 10048 error
Not entirely true.
When the client wants to connect a second, third, etc. time to the same server it should normally set LocalPort to 0 to request a fresh ephemeral port number. Otherwise you end up with those pesky errors because the old TCP connection may still be in TIME-WAIT state in the TCP connection table at the client. On the first use of a client socket LocalPort is already 0 so it doesn't matter.
The server doesn't have this issue because Accept sets both values for the server's connection socket. The listening socket doesn't give a hoot about RemotePort because it isn't relevant.
-
May 8th, 2008, 03:11 AM
#12
Thread Starter
Member
Re: Winsock 10048 error
Hi All,
Thanks all for your replies. After much playing around with winsock, I am well underway to understanding how the whole process works.
This post seems to point the closest to what is going on. If I use 'netstat' command from command prompt i am shown that the port is in a TIME_WAIT state as suggested.
Originally Posted by dilettante
Not entirely true.
When the client wants to connect a second, third, etc. time to the same server it should normally set LocalPort to 0 to request a fresh ephemeral port number. Otherwise you end up with those pesky errors because the old TCP connection may still be in TIME-WAIT state in the TCP connection table at the client. On the first use of a client socket LocalPort is already 0 so it doesn't matter.
The server doesn't have this issue because Accept sets both values for the server's connection socket. The listening socket doesn't give a hoot about RemotePort because it isn't relevant.
Upon the form_queryunload event of my client I have:
Code:
If sckTCP.State = 7 Then
sckTCP.SendData STARTCHAR & "CLIENT|SETUP|CLOSEREQ|" & MyPid & "|" & ENDCHAR
Cancel = True
End If
MyPid is a variable stored on the server which assigns player(MyPid) = sckConn(MyPid) so I can tell which client is trying to close the connection.
The server has a DataArrival event, cuts the message down to CLOSEREQ, then sends back "CLOSEOK", then theres a DoEvents (to make sure the data actually gets sent before the connection is closed at the server end.
Finally the client receives CLOSEOK then closes the connection at its end. Both using .Close method correctly, and again I'm only using sckConn(0) becuase there is only the one client trying to connect at the moment.
So IF the server closes using the .Close method, and the client closes using the .Close method, the server should immediately be able to listen again and the client can reconnect on the exact same port without delay?
Thanks again,
Tim.
-
May 7th, 2008, 09:45 PM
#13
Re: Winsock 10048 error
Not entirely true.
I'm sure you are absolutely correct however I believe we are correct enough to set the guy on the right track of how client/server applications work without getting into any deeper technologies about the usage which I'm sure he will be able to grasp in due time.
-
May 8th, 2008, 03:21 AM
#14
Re: Winsock 10048 error
The only issue with the implementation of the logic I have, on first inspection, is the bit about DoEvents. That does not guanantee the data has been sent. I'd put some code in the SendComplete event which is triggered after the all the data has been sent.
In fact the 'conversation' about closing can be managed with just the .Close method and the _Close event. If the Client issues a .Close the _Close event in the Server will be triggered. When that happens the Server can perform any 'tidying up' since it has all the necessary information (ie the Index argument will tell the Server which socket has closed and from that deduce the User etc)
-
May 8th, 2008, 03:37 AM
#15
Thread Starter
Member
Re: Winsock 10048 error
So if I close the socket on the server side, do both sides fire a _close event?
and then I'd just say sckClient.Close under sckClient_Close and sckServer.Close under sckServer_Close event?
Just for your reference here is my code on the server, after a connection/disconnection is ensures that there is always a socket loaded, and listening, for new connections. If a control is already loaded, but no current connection it sets that control as the listening control, and closes all other non-connected controls.. the line in orange is when I get my error, but only after the client has disconnected and the server is trying to setup a valid socket to listen on..
Code:
Public Sub EnsureReady()
Dim I As Long
Dim U As Long
'make sure a winsock is ready for another player to come in
For I = LBound(HP) To UBound(HP)
If HP(I).AvailableSlot = True Then 'find first available slot
If HP(I).Declared = False Then 'available slot already with a winsock ready to go
Load sckConn(I)
HP(I).Listening = True
With sckConn(I)
.Close
.LocalPort = TCP_SendPort
.Listen
End With
HP(I).Declared = True
Exit For
Else 'already been declared, and is free, stop all other socks listening and exit sub
sckConn(I).Close
DoEvents
HP(I).Listening = True
sckConn(I).LocalPort = TCP_SendPort
sckConn(I).Listen
If I < UBound(HP) = True Then
For U = (I + 1) To UBound(HP)
If HP(U).Listening Then
sckConn(U).Close
HP(U).Listening = False
End If
Next U
End If
Exit For
End If
End If
Next I
End Sub
Last edited by emtark; May 8th, 2008 at 03:49 AM.
Tim.
-
May 8th, 2008, 05:41 AM
#16
Re: Winsock 10048 error
That's an unusual way to manage the listening, but whatever. The error would suggest to me that there is already a socket listening on that Port and you can't have more than one listener on the same Port.
-
May 8th, 2008, 06:44 AM
#17
Thread Starter
Member
Re: Winsock 10048 error
Well apart from feeling completely stupid, at least I learnt something.
It was that EnsureReady subroutine running wrong.
The second half where it has to close off all other listening winsock controls that are listening on the same port was not being run before attemping to listen on another winsock control..
I just shifted some lines around and it seems to be working properly.
I'll post the code in case anyone is having similar problems or wants to implement a multiple connection server and be able to re-use existing winsock controls.
Thanks all for your help!
Tim.
[code shown below, blue code USED to be before red code.. swapped them to as you see here.. working well!]
Code:
Public Sub EnsureReady()
Dim I As Long
Dim U As Long
'make sure a winsock is ready for another player to come in
For I = LBound(HP) To UBound(HP)
If HP(I).AvailableSlot = True Then 'find first available slot
If HP(I).Declared = False Then 'available slot already with a winsock ready to go
Load sckConn(I)
HP(I).Listening = True
With sckConn(I)
.Close
'.RemotePort = TCP_ListenPort
.LocalPort = TCP_SendPort
.Listen
'.LocalPort = TCP_SendPort
End With
HP(I).Declared = True
Exit For
Else 'already been declared, and is free, stop all other socks listening and exit sub
sckConn(I).Close
DoEvents
If I < UBound(HP) = True Then
For U = (I + 1) To UBound(HP)
If HP(U).Listening Then
sckConn(U).Close
HP(U).Listening = False
End If
Next U
End If
HP(I).Listening = True
sckConn(I).LocalPort = TCP_SendPort
sckConn(I).Listen
Exit For
End If
End If
Next I
End Sub
-
May 8th, 2008, 07:31 AM
#18
Re: Winsock 10048 error [RESOLVED]
So if I close the socket on the server side, do both sides fire a _close event?
and then I'd just say sckClient.Close under sckClient_Close and sckServer.Close under sckServer_Close event?
Not exactly.
The _Close Event is triggered whenever the other side issues the .Close command.
If the client closes his socket then the _Close Event on the server is triggered and if the server closes his socket then the _Close Event on the client is triggered.
In general, the _Close Event is triggered for either the server or the client whenever the other side closes their socket. You never call your own _Close Event; it is always triggered from the other side.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|