|
-
Apr 25th, 2000, 05:41 AM
#1
Does any one know of a good chat program tutorial? thanks...
-
Apr 25th, 2000, 06:22 AM
#2
Fanatic Member
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|