Results 1 to 7 of 7

Thread: Winsock Problem

  1. #1

    Thread Starter
    Member
    Join Date
    Nov 2000
    Location
    Manila, Philippines
    Posts
    51

    Angry Winsock-Port Trouble.. Help, anyone?

    Hi,
    I got a problem with Winsock you might have answers to.
    Here is the situation:
    I experimented with a client/server app in one machine only. I have a form, 3 Winsocks, and two textboxes, and 1 command button.
    I am trying to send messages to my own machine...

    WINSOCKS:
    (for sending)
    Name: Send
    LocalPort: 1028

    (for listening)
    Name: Listen
    LocaPort: 1029

    Name of my PC on network: Nil

    CODE:

    On form load, I invoked the listener to listen:
    Listen.LocalPort = 1029
    Listen.Listen

    On a command button:
    Send.LocalPort=1028
    Send.Connect "Nil",1029

    (I hope I need not explain this further... the application works fine...)
    HOWEVER, when I disconnect (Send.Close), of course it disconnects... BUT when I try to connect again on the same localport:
    Send.LocalPort = 1028
    Send.Connect "Nil",1029
    (This is the same as the code above...)

    The damn thing cant connect. ERROR: Port in use!!!
    I hate to use another port. Is there a way to work around this? HOWEVER, after sometime, the port is free again!!! (I hate to wait too)

    I want a clean close, not just the close method. I think the close method does not free the port. The damn thing thinks the port is still in use after I invoke the Close Method.

    So I guess, my question is, is there a way to free a port? And, Why on earth is this happening?? (I know the basics of TCP/IP with Winsock... I just need to know the basics of PORTS... hehe...)

    I have scrambled over tons of crap explanations but nothing tells me how to work around this... Nothing tells me something about a 'Neat' disconnect.

    Any advice on this, please? Any help would be very much appreciated.

    Thanks.
    Jonaxse


    [Edited by jonaxse on 11-02-2000 at 02:15 AM]
    Programmers dont byte, they just nibble a bit.

  2. #2
    Guest
    You don't need to set a LocalPort for your server, all you need to do is:

    Server
    Code:
    Listen.LocalPort = 1028
    Listen.Listen
    Client
    Code:
    Send.RemotePort = 1028
    Send.RemoteHost = ServerName
    Send.Connect
    But to answer you question, by doing it this way, when on side of the connection is closed, the other side will close and the port used will close. Not needing you to finish off other things yourself.

    Sunny


    [Edited by sunnyl on 11-02-2000 at 02:26 AM]

  3. #3

    Thread Starter
    Member
    Join Date
    Nov 2000
    Location
    Manila, Philippines
    Posts
    51

    Smile Thanks.

    I did not realize... Hmm...
    When the client connects, I dont need to set the localport? Is that what u are saying?

    Well, if the way I understand it, you are saying that I do NOT need a localport for the client... the client just needs a remoteport and remotehost, to connect.

    When a winsock client connects to a remote port and you do not provide a localport for the client, does the client generate a random port number to use for that?


    Anyway, Thanks for the suggestion, Im gonna try it.
    Yer help is very much appreciated.
    Jonn
    Programmers dont byte, they just nibble a bit.

  4. #4
    Guest
    You may be getting the wrong impression that each port is only a one way communication pathway, however this isn't the case. Each port can send/receive, it is simply a matter of pointing the client to the port that the server is listening to. For example, HTTP flows through port 80, but of course, communication with a browser and web server is a two way communication, yet it is all done through port 80.

    From MSDN:
    If you are creating a client application, you must know the server computer's name or IP address (RemoteHost property), as well as the port (RemotePort property) on which it will be "listening." Then invoke the Connect method.

    If you are creating a server application, set a port (LocalPort property) on which to listen, and invoke the Listen method. When the client computer requests a connection, the ConnectionRequest event will occur. To complete the connection, invoke the Accept method within the ConnectionRequest event.


    Sunny

  5. #5

    Thread Starter
    Member
    Join Date
    Nov 2000
    Location
    Manila, Philippines
    Posts
    51
    Thanks for the reply... I think I found the problem.
    Problem (I think): When the client connects to the server, the server designates another winsock control to accept the request ID (perhaps on a control array)...
    But when the client disconnects thru the .Close method, the winsock on the server didnt know about it (am I right?)... so It still maintains the connection thru that port, regardless of the client's status (I think this is where timeouts get useful). So when I try to reconnect on the same port, it says "Port is being used.".... Simply because I only invoked the .Close method on the client (does the server have to close the IP connection too?)

    This is my solution: (please give me some advice on whether this is the best solution there is...)
    On the Client side, before i disconnect, I send a message (i.e. "/Close" <--- this is just some sort of my own protocol... ) When the server receives this message, it sends back a confirmation..(i.e. "/CloseGoAhead") then the server terminates the connection on its side thru the .Close method. When the client receives the message, (i.e. "/CloseGoAhead") it closes its connection too (.Close)... So now, the port is free!!! (I think)

    So when I connect back an instant later, It works !!!
    I think the protocol thing is a good one! But what happens is when the connection is terminated by something else... Maybe this is where timeouts get handy.

    I just wanna know if it is recommended or would you call it a good practice for a client to periodically send messages to the server, notifying it that the client is still connected? (much like a PING)... it the client does not send any more messages for a specified time, the server automatically closes the connection...(Hmmm.. this is like the IRC...hehe)

    Thanks for the advice... I now invoke the .Connect method on the client without specifying a localport. I guess the client randomly chooses an available port if u dont specify one (or does it?)

    Anyway, what you told me was very helpful.

    for lCtr = 1 to 1000000
    Me.Say "Thanks a lot!"
    next lCtr

    You.NiceGuy = True
    Me.Idiot = True 'I hope not...

    Jonn
    Programmers dont byte, they just nibble a bit.

  6. #6
    Guest
    Ahh...I'm sorry, I didn't quite read the question all that clearly the first time round. But I now understand your problem more clearly.

    After you invoked Close, you couldn't reconnect. The problem and solution is simple.

    When you have connected, you are at state 7 (connected), after invoking Close on the client it will goto state 0 (closed). However, on the server side (or the side that didn't invoke the Close method) will goto state 8 (peer closing connection) for sometime before it goes back to state 0 (closed). So when you tried to reconnect to it when it is still listening/closing an error occurs.

    To solve this, after you know the last transaction has occurred (see below), you should restart the listening process in the listener with something like:

    Code:
    Public Sub RestartConnection()
       wskListen.Close
       wskListen.LocalPort = 1000
       wskListen.Listen
    End Sub
    To know when to reinvoke the Listen method on the server, the client should attach a little string to the end of its last message, and when the server parses the received string and sees that particular string, it will close on its own.

    For example,
    Code:
    Private Sub cmdClose_Click()
       wskClient.SendData YourMessage & "|Close|"
       LastMessage = True
    End Sub
    
    Private Sub wskClient_SendComplete()
       If LastMessage = True Then
           wskClient.Close
           LastMessage = False
       End If
    End Sub
    and on the server end:

    Code:
    Private Sub wskListen_DataArrival(ByVal bytesTotal As Long)
        Dim str As String
    
        wskListen.GetData str
    
        If Right(str, 6) = "|Close|" Then
            Call RestartConnection
        End If
    End Sub
    
    Public Sub RestartConnection()
       wskListen.Close
       wskListen.LocalPort = 1000
       wskListen.Listen
    End Sub
    This code will get the server to start listening again as soon as a 'finished' mark is received.

    I guess the client randomly chooses an available port if u dont specify one (or does it?)
    Yes, it picks a random port.

    Sunny

    [Edited by sunnyl on 11-03-2000 at 10:32 PM]

  7. #7

    Thread Starter
    Member
    Join Date
    Nov 2000
    Location
    Manila, Philippines
    Posts
    51
    Thanks so much...
    Your words of wisdom cleared things up...

    =====================
    1.> Client chooses a random port on connect.
    2.> Both sides has to close the connection or the server does a timeout (its gonna take long)
    3.> The protocol is important...hehe
    4.> Im happy.

    Thanks.

    Ur help had been most invaluable.
    Programmers dont byte, they just nibble a bit.

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