Results 1 to 10 of 10

Thread: [RESOLVED] A question in Winsock

  1. #1

    Thread Starter
    Member
    Join Date
    Apr 2008
    Posts
    43

    Resolved [RESOLVED] A question in Winsock

    This is my problem.
    I have a server and many clients are connected to each other "thru" the server.
    Now If client-1 wants to send a file to client-2 then both of them should be
    connected directly using another winsock.
    How can I achieve this ? (Bcoz client-1 does not know the ip of client-2).

  2. #2
    PowerPoster
    Join Date
    Nov 2002
    Location
    Manila
    Posts
    7,629

    Re: A question in Winsock

    There should be a means of resolving IP adresses, e.g. usernames can be checked at server to retrieve corresponding IP address.

  3. #3

    Thread Starter
    Member
    Join Date
    Apr 2008
    Posts
    43

    Re: A question in Winsock

    How can i get the External Ip address.
    If I use the RemoteHost property i recieve only their network ip address.

  4. #4
    "Digital Revolution"
    Join Date
    Mar 2005
    Posts
    4,471

    Re: A question in Winsock

    This is why you need to develop a protocol for your program. AKA: a list of commands prefixed with a number so the program knows what kind of data is being sent. I don't do it quite this way anymore, but here is an example.

    You can use any numbers you like, and don't even have to use numbers at all, but it's just an example:

    Client (to server):
    Code:
    Message: 100 Nickname MessageText
    Private Message: 200 Nickname Recipient MessageText
    Server (to client(s)):
    Code:
    Message (relay to all clients): 100 Nickname MessageText
    Private Message:
        To recipient: 200 Sender Message
        To sender:
            User not online: 201 Recipient (note: 201 for error and not 200)
            Sent: 200 Recipient Message
    That is a very basic example of a very basic protocol. To do what you're asking, you should store the IP address of every connected client (or use Winsock(Index).RemoteHostIP on the server), along with their nickname.

    Then you could update the protocol with something like:

    Client (to server):
    Code:
    File transfer request: 300 Recipient FileName Size
    File transfer response:
        Accepted: 301 Sender FileName Size
        Denied: 302 Sender FileName Size
    Server (to client(s)):
    Code:
    File transfer request:
        To recipient: 300 Sender FileName Size
    File transfer response:
        To sender:
            Accepted: 301 Sender FileName Size IPAddress
            Denied: 302 Sender FileName Size
    I always write out a simple protocol.txt file like the above before even beginning on the VB code. Then the framework for your client/server project is done and already thought out and it's just a matter of writing the code for it.

  5. #5

    Thread Starter
    Member
    Join Date
    Apr 2008
    Posts
    43

    Re: A question in Winsock

    I do have my own protocol.
    But that's nothing to do with my question.

  6. #6
    PowerPoster
    Join Date
    Nov 2002
    Location
    Manila
    Posts
    7,629

    Re: A question in Winsock

    Yes it has. Clients ask the server for details regarding other clients in order to resolve IP addresses... implied is the protocol DigiRev mentioned.

  7. #7

    Thread Starter
    Member
    Join Date
    Apr 2008
    Posts
    43

    Re: A question in Winsock

    But even the server does not know the "external" ip address of other clients.

  8. #8
    "Digital Revolution"
    Join Date
    Mar 2005
    Posts
    4,471

    Re: A question in Winsock

    I wasn't sure if you were already using a protocol or not, I guess I assumed you weren't...but I was mostly saying just request the IP of the other user from the server...

    You should store info on the server for each client in something like a UDT array, and re-dimension that array as new clients connect (the same as you are doing with the Buffer string for each client in your "BlueChat project").

    Ex:

    Code:
    'In your module (Module1.bas)
    Public Type CLIENT
        strNickname As String
        strIPAddress As String
    End Type
    
    Public udtClients() As Client
    
    Public Function UBClients() As Integer
        On Error GoTo ErrorHandler
        UBClients = CInt(UBound(udtClients))
        Exit Function
    ErrorHandler:
        UBClients = -1
        Exit Function
    End Function
    Then modify your Winsock_ConnectionRequest() event.
    Code:
    Private Sub Winsock1_ConnectionRequest(Index As Integer, ByVal requestID As Long)
        '
        'The winsock(0) is the control that is only listening and only accepts
        'the connections.
        '
        'Check if the Index is 0
        
        'Empty client
        Dim udtEmpty As CLIENT
        If Index = 0 Then
            
            'check all the existing winsock's state
            'If closed then accept the connection in this itself and flush its buffer.
            For i = 1 To ind
                If Winsock1(i).State = sckClosed Then
                    Winsock1(i).Accept requestID
                    Buffer(i) = ""
                    'Reset client info.
                    udtClients(i) = udtEmpty
                    'Store their IP address.
                    udtClients(i).strIPAddress = Winsock1(i).RemoteHostIP
                    Exit Sub
                End If
            Next
            
            'Did not find any winsock that is closed. so increment the ind by 1.
            ind = ind + 1
            
            'Load the Winsock
            Load Winsock1(ind)
            
            'Create a new buffer for the new winsock with the same index number.
            ReDim Preserve Buffer(ind)
            
            'Create new user array item.
            ReDim Preserve udtClients(ind) As CLIENT
            
            'Accept the connection.
            Winsock1(ind).Accept requestID
            
            udtClients(ind).strIPAddress = Winsock1(ind).RemoteHostIP
        End If
    End Sub
    Now you can access a user's information using the Index of the Winsock control, ex: udtClients(Index).strNickname

    Then you would set their nickname when they login. I haven't looked at your code much so this might be off, but it would probably go in the DataArrival() event:

    Code:
    Private Sub Winsock1_DataArrival(Index As Integer, ByVal bytesTotal As Long)
        Dim Record As String 'Net data recieved
        Dim EORPos As Long 'Pos of eod mark
        Dim Finished As Boolean '..finished processing or not?
    
        'Get the message in a str Variable.
        Winsock1(Index).GetData message
        
        'Append the data to the particular client's buffer.
        Buffer(Index) = Buffer(Index) & message
        
        Do
            'Check wheather the buffer contains the eod mark
            EORPos = InStr(Buffer(Index), eod)
            
            'If so then...
            If EORPos > 0 Then
                
                'remove the eod mark and store it in the record.
                Record = Mid(Buffer(Index), 1, EORPos - 1)
                
                                
                                '******PROCESSING PART*******'
                
                
                If datapassthru(Record) = 0 Then
                    auth = authenticate(Record)
                    If auth = False Then
                        Winsock1(Index).SendData "***|\/|***P" & "0 " & "Invalid Username/Password. Connection Forbidden!" & eod
                    Else
                        Winsock1(Index).SendData "***|\/|***P" & "1 " & "Connected to " & Winsock1(0).LocalIP & eod
                        '// MODIFICATION //
                        'Set user's nickname?
                        Dim strU As String
                        strU = getuser(Record)
                        udtClients(Index).strNickname = strU
                        '// EOF MODIFICATION //
                    End If
                ElseIf datapassthru(Record) = 1 Then
                    If checkC(Record) = True Then
                        Winsock1(Index).SendData "***|\/|***C" & "0" & eod
                    Else
                        Winsock1(Index).SendData "***|\/|***C" & "1" & eod
                    End If
                ElseIf datapassthru(Record) = 2 Then
                    CreateNew Record
                    Winsock1(Index).SendData "***|\/|***N" & "Your ID has been succesfully registered in the Bluehat server." & vbCrLf & _
                                                          "You can now login with your username and password." & eod
                ElseIf Record = "*.*" Then
                    Winsock1(Index).Close
                Else
                    For i = 1 To ind
                        If Winsock1(i).State = sckConnected Then
                            Winsock1(i).SendData Record & eod
                        End If
                    Next
                End If
                
                
                                '********END OF PROCESSING PART*******'
                
                'Check wheather if there is any remaining data
                If EORPos + Len(eod) < Len(Buffer(Index)) Then
                    
                    'then move it to the front of the buffer and loop again.
                    Buffer(Index) = Mid(Buffer(Index), EORPos + Len(eod))
                
                Else '..no remaining data.
                                
                    'then flush the buffer and exit the loop.
                    Buffer(Index) = ""
                    Finished = True
                    
                End If
            
            Else 'You did not find any eor mark
                
                'Exit the loop and wait for the remaining data.
                Finished = True
                
            End If
        
        Loop Until Finished = True 'End loop when finished = true
    
    End Sub
    Now you can access a user's nickname and IP address using the Index argument of a Winsock event.

    Then you would use the irrelevant code that had nothing to do with your question to request the IP address of another user.

  9. #9
    PowerPoster
    Join Date
    Nov 2002
    Location
    Manila
    Posts
    7,629

    Re: A question in Winsock

    Quote Originally Posted by VIGGY808
    But even the server does not know the "external" ip address of other clients.
    Then how do you think direct connections are established in IRC and other chat networks? The server handles it all... in its rudimentary form server keeps track of unique username to IP mapping.

  10. #10

    Thread Starter
    Member
    Join Date
    Apr 2008
    Posts
    43

    Re: A question in Winsock

    Thanks DigiRev and leinad91.

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