Results 1 to 2 of 2

Thread: How To...

  1. #1
    Guest

    Post

    Does any one know of a good chat program tutorial? thanks...

  2. #2
    Fanatic Member
    Join Date
    Feb 2000
    Location
    Japan
    Posts
    840
    Think I've posted this before...


    Using the Winsock Control to Receive Data {06-Aug-1998}

    The Winsock control in VB 5.0 is a relatively thin wrapper around the
    winsock API. As such it works fairly well but can be difficult to understand
    if you are not familiar with the underlying TCP/IP protocol. The biggest
    issue is that there is no relationship between the number and size of things
    send with SendData and the number and size of items received in the
    DataArrival event. You may send a single 8KB buffer and receive 16 512-byte
    chunks or vice-versa. It is totally up to the programmer to interpret the
    incoming data and to buffer any partial items recieved. There are three
    common ways of doing this:
    1. delimit each item sent with something specific. For text-only the normal
    delimiter is a CR/LF pair at the end of each line.
    2. prefix each item with one or two bytes indicating the length of the data
    to follow. This is useful if the data in binary and can contain any
    character so no delimiter is possible.
    3. open a connection, transmit everything, and close the connection. The
    FTP protocol uses this for data transfers while the command transfers are
    done using option 1 above. It is useful for sending large amounts of data
    as a single "chunk" as in transferring a complete file.

    The code below is an extremely simple chat server which accepts telnet
    connections from clients. Every complete line received is echoed to all
    other clients and partial lines are buffered. It is meant only as a
    demonstration of (1) how to buffer and parse incoming data and (2) how to
    deal with multiple clients.

    Note that when dealing with multiple clients it is necessary to use the
    DoEvents statement. If this is omitted then some SendData commands will
    be suspended or discarded. In more robust applications it may be
    necessary to use module-level flags to prevent DoEvents from causing
    unexpected recursion problems.
    (See http://home.earthlink.net/~butlerbob.../doevents.htm)
    To try this code, start a new project and place a listbox (LIST1) and a
    Winsock control (Winsock1) on Form1. Set the Index property of Winsock1
    to 0 in order to create a control array. Then paste the following code:

    Code:
    Option Explicit
    ' Need a place to buffer incoming data
    Private Const MAX_CONNECTIONS = 10
    Private msBuffer(1 To MAX_CONNECTIONS) As String
    
    Private Sub Form_Load()
    ' Set up Winsock control to wait for connections
    Winsock1(0).LocalPort = 23 ' this is the default TELNET port
    Winsock1(0).Protocol = sckTCPProtocol
    Winsock1(0).Listen
    End Sub
    
    Private Sub Form_Unload(Cancel As Integer)
    Dim x As Long
    ' close all connections and unload controls
    Winsock1(0).Close
    For x = 1 To Winsock1.UBound
      Winsock1(x).Close
      Unload Winsock1(x)
    Next x
    ' always release the form object variable
    Set Form1 = Nothing
    End Sub
    
    Private Sub Winsock1_Close(Index As Integer)
    ' One of the clients went away
    If Len(msBuffer(Index)) > 0 Then
      ' we have a partial buffer left over....
      DataReceived Index, msBuffer(Index)
      msBuffer(Index) = ""
    End If
    Winsock1(Index).Close
    End Sub
    
    Private Sub Winsock1_ConnectionRequest(Index As Integer, _
      ByVal requestID As Long)
    Dim x As Long
    ' new connection request from a client
    ' first check all existing elements of the control array
    For x = 1 To Winsock1.UBound
      If Winsock1(x).State = sckClosed Then
        ' we have a slot that is currently available
        msBuffer(x) = "" ' initialize buffer
        Winsock1(x).Accept requestID
        ' send "hello" info to the client (if desired)
        SendInfo x, "Connected as ID " & CStr(x)
        Exit Sub
      End If
    Next x
    ' all current elements are in use -- need new one
    If Winsock1.UBound < MAX_CONNECTIONS Then
      ' we have room to add one so load new instance
      x = Winsock1.UBound + 1
      Load Winsock1(x)
      ' and do the same initialize & welcome...
      msBuffer(x) = ""
      Winsock1(x).Accept requestID
      SendInfo x, "Connected as ID " & CStr(x)
    End If
    ' if no instances were available no Accept was done
    ' and the request will be rejected automatically
    End Sub
    
    Private Sub Winsock1_DataArrival(Index As Integer, _
      ByVal bytesTotal As Long)
    Dim sTemp As String
    Dim x As Long
    ' something came in... if we are ready for it
    If Winsock1(Index).State = sckConnected Then
      Winsock1(Index).GetData sTemp ' get the data
      msBuffer(Index) = msBuffer(Index) & sTemp ' add to buffer
      ' check for any/all CRLF in the data stream
      ' need to loop because there could be several
      Do
        x = InStr(msBuffer(Index), vbCrLf)
        If x < 1 Then Exit Do ' no more found
        ' got a line - strip it from the buffer and process
        sTemp = Left$(msBuffer(Index), x - 1)
        msBuffer(Index) = Mid$(msBuffer(Index), x + 2)
        DataReceived Index, sTemp
      Loop
    End If
    End Sub
    
    Private Sub Winsock1_Error(Index As Integer, _
      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)
    ' error occurred on one of the connections
    If Len(msBuffer(Index)) > 0 Then
      ' we have a partial buffer left over....
      DataReceived Index, msBuffer(Index)
      msBuffer(Index) = ""
    End If
    ' reset this connection
    Winsock1(Index).Close
    End Sub
    
    Private Sub DataReceived(ByVal Index As Integer, _
      ByVal DataBuffer As String)
    Dim x As Long
    ' report last 100 items to listbox on form
    If List1.ListCount > 99 Then List1.RemoveItem 0
    List1.AddItem CStr(Index) & ": " & DataBuffer
    List1.ListIndex = List1.NewIndex
    ' now copy the data to all other connections...
    ' (just for something to do)
    For x = 1 To Winsock1.UBound
      If x <> Index Then
        SendInfo x, CStr(Index) & ": " & DataBuffer
      End If
    Next x
    DoEvents
    End Sub
    
    Private Sub SendInfo(ByVal Index As Integer, _
      ByVal DataBuffer As String)
    ' need to send info to client
    ' first be sure the port is fully open or closed
    Do Until Winsock1(Index).State = sckConnected _
      Or Winsock1(Index).State = sckClosed
      DoEvents ' nasty, but needed with Winsock controls
    Loop
    ' then send if it is open...
    If Winsock1(Index).State = sckConnected Then
      Winsock1(Index).SendData DataBuffer & vbCrLf
      DoEvents
    End If
    End Sub

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