PDA

Click to See Complete Forum and Search --> : set data types in winsock on receive


milligreen
Mar 27th, 2007, 08:20 PM
I want to have in my winsock control, it take and send the name of a player for a game, and a value, so a string and an integer. how do i make it in the data arrival to make a part that can receive a name, string, and a part to receive a score, an integer. also, this means i would need the senddata part to, to send a name and then an score.

ccoder
Mar 28th, 2007, 09:35 AM
Send the data as a UDT. The Winsock control does not understand UDTs, so in your code you will have to move it to/from a byte array in order to send/receive the data. You can use the CopyMemory to move the UDT to/from the byte array.

For example:

Public Type dclPlayerRec
PlayerValue As Integer
PlayerName As String * 20
End Type

Public Player As dclPlayerRec ' the IPC structure
Public bTBuff() As Byte ' buffer for sends/receives

Public Declare Sub CopyMemory Lib "KERNEL32" _
Alias "RtlMoveMemory" (hpvDest As Any, _
hpvSource As Any, _
ByVal cbCopy As Long)

Note that the string must be fixed length, otherwise PlayerName will simply contain the BSTR (address) of the string.

To copy the UDT to/from a byte array, code the API calls are:
for the send routine

ReDim bTBuff(Len(Player) - 1)
CopyMemory bTBuff(0), Player, Len(Player)
tcpClient.SendData bTBuff

for the receive routine

ReDim bTBuff(bytesTotal - 1)
tcpServer(Index).GetData bTBuff, vbArray + vbByte, bytesTotal
CopyMemory Player, bTBuff(0), Len(Player)

Several other things to consider.

If the string is very large, you may have to write the DataArrival code to handle receiving the UDT in pieces. Let me know if you need help with that.

If both client and server are written in VB you should not have any problems with the Integer value. If one side or the other is written in a different language or is running on a non-Windows platform, you may have to convert the Integer to/from network byte order (big-endian) before sending it and after receiving it. There are API calls for converting to/from network byte order.

For Integers:
ntohs - network to host short
htons - host to network short

For Longs:
ntohl - network to host long
htonl - host to network long

milligreen
Mar 28th, 2007, 03:05 PM
well, im pretty sure i do not need to do that much, because their are pletny of programs i have with source that use only winsock, and for example, a chat program i have which sends a name of the chatter witht he connection, and then whatever you type to send

DigiRev
Mar 28th, 2007, 03:33 PM
I think sending as a UDT like ccoder said is the best way, but the easiest way would be to do something like:

Winsock.SendData "INFO/" & strPlayerName & "/" & CStr(intScore) & vbCrLf

Then on the data arrival:

Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)
Dim strData As String, strPackets() As String
Dim lonLoop As Long, strInfo() As String

Winsock1.GetData strData, vbString, bytesTotal

'Split up the "packets".
'A packet looks like this in this example:
'INFO/PlayerName/Score

'Where INFO tells the program what kind of data is in the packet.
'Each individual packet is separated by a vbCrLf (new line).
'We will split the data into packets by the vbCrLf
'Then we will process each packet individually.

'Find vbCrLf in data.
If InStr(1, strData, vbCrLf) > 0 Then
'Split up each packet.
strPackets() = Split(strData, vbCrLf)

'Loop through all packets.
For lonLoop = 0 To UBound(strPackets())
'Make sure packet isn't empty.
If Len(strPackets(lonLoop)) > 0 Then
'strPackets(lonLoop) looks like this in this example:
'INFO/PlayerName/Score

'Check what kind of packet it is:
Select Case Left$(strPackets(lonLoop), 4)

'It is an info packet.
Case "INFO"
'Split up the packet into different chunks.
'So we can separate the playername from the score.
strInfo() = Split(strPackets(lonLoop), "/")

'Now:
'strInfo(0) = INFO
'strInfo(1) = PlayerName
'strInfo(2) = Score

MsgBox strInfo(1) & " has a score of " & strInfo(2), vbInformation

'Add other packet types here if u want:
'Case "blah"
'
End Select

End If

Next lonLoop
End If

Erase strPackets()
Erase strInfo()
End Sub

Not really the best way but it's an example.