Ben said:
I need to send data from a client to a server. In the server code I have:
s = ServerSocket.Accept()
If (s.Connected = False) Then
MsgBox("Unable to connect", , "Server Error")
Exit Sub
End If
While (s.Connected = True)
SBytes = s.Receive(SBuffer, 0, SBuffer.Length,
Net.Sockets.SocketFlags.None)
MsgBox(SBuffer)
End While
I want to print the data the server received. Right now the server program
crashes when it receives some data. How can I print the data I receive? If
anyone can recommend a good VB2005 book that deals with socket programming I
would love to hear about it.
Thanks,
Ben... I don't know of any good (or bad for that matter) VB.NET socket
programming books. But, I will point you to the .NET documentation.
There are some ok examples there and it covers both synchronous and
asynchronous socket clients and servers.
Here is a link to the web version:
http://msdn2.microsoft.com/en-us/library/b6xa24z5(VS.80).aspx
You should probably pay close attention to the asynchronous model. It
is actaully much more scalable then the synchronous model. Especially
if your server needs to support multiple connections (most do
Comments on your code:
s = ServerSocket.Accept()
Ok..
If (s.Connected = False) Then
MsgBox("Unable to connect", , "Server Error")
Exit Sub
End If
I wouldn't bother with this. In fact, I wouldn't bother with the
Connected property at all. It is unreliable and you don't need it.
While (s.Connected = True)
SBytes = s.Receive(SBuffer, 0, SBuffer.Length,
Net.Sockets.SocketFlags.None)
MsgBox(SBuffer)
End While
If this is in the same place as the accept - then this is probably bad.
The problem is you're not going to be able to process other requests
while your in this loop. If your going to use a sync model (blocking
socket calls) - you would be much better off spawing a thread to handle
the actual communication with the client. I tend to create a sub
object that handles the request, that the server stores in a
collection. The connection object then spawns a thread for the actual
request and fires an event back to the server object when it is done
(so that the connection object can be removed from the collection).
This way, your sever can go back to what it should be doing - listening
for connections.
Your loop here is a problem anyway. First off, how do you know you've
recieve all the data? You aren't guarenteed to recieve all your data
in one recieve. You aren't even guarenteed that the data in a single
recieve was sent in a single send. Basically, you need some kind of
end-of-transmission marker. Typically, if this is string data it will
be a CR/LF combo - but not always for example, SMTP uses a CR/LF.CR/LF
to signal the end of the body of an email message. The reason this is
important is that Recieve is a blocking call - in other words, it will
wait until either there is data to be read or the socket to close
before returning. You can tell the difference, because recieve will
return 0 when the socket is closed (that's why you don't really need
the connected property). So, if your simply reading data until the
socket closes, your loop would look more like:
dim buffer() as byte = new byte (4098)
dim count as integer
dim data as system.text.stringbuilder
count = s.recieve (buffer, 0, buffer.length, socketflags.none)
while count <> 0
data.append (encoding.ascii.getstring (buffer, 0, count)
count = s.recieve (buffer, 0, buffer.length, socketflags.none)
end while
messagebox.show (data.ToString ())
Anyway - I'm not sure if this rambling really helped your or not...
But, feel free to ask more specifics if you would like.
HTH