VBNET:Sockets
From GPWiki
[edit] Network Sockets(It is easier to use the TcpListener and TcpClient classes than this) This will be an article on sending and recieving data over networks, to and from a client or server. the article will be based off of a sockets library that i have written using the system.net.sockets.socket class. you may download the source here:
if you have ever attempted to write your own socket, you may have messed around with the System.Net.Sockets.Socket class before. in doing this, you probably noticed a certain set of functions such as BeginAccept, EndAccept, BeginRecieve, EndRecieve, and so on. well, were going to learn just exactly how to use these. [edit] The socketthe reason why this is first, is because it is the backbone for each socket. before we can do anything, we need to first declare our socket Dim mySocket as System.Net.Sockets.Socket this is great and all, but we need to set up our socket to tell the operating system exactly what kind of socket it is. mySocket = New System.Net.Sockets.Socket(System.Net.Sockets.AddressFamily.InterNetwork _ , System.Net.Sockets.SocketType.Stream _ , System.Net.Sockets.ProtocolType.Tcp) there are many other socket types, but this will create a tcp socket for us (you can also change tcp to udp, if thats what you want) [edit] StateObjectIf you have ever done multithreading, you might have noticed that you cant exactly pass data directly to a thread. You have to create a class or structure and stick it in a field until that thread picks it up. Thats pretty much what the StateObject is used for, except that its not kept in your class. This is the code you will need in order to: accept, send data, recieve data public class StateObject public Socket as System.Net.Sockets.Socket public Size as Integer = 32767 public Buffer(32767) as Byte end class [edit] ClientsThis is outlined as clients, but really its more then just that. I am combining clients with sending and recieving data, even though these two elements are also used in sessions. the reason i am doing this is so we can connect to a server, and request for data to be sent back. when you connect to a server, you will be using two functions for this: BeginConnect EndConnect heres how they work together: Public Sub Connect() dim State as New StateObject() mySocket.BeginConnect(new System.Net.IPEndPoint(System.Net.Dns.Resolve("www.google.com").AddressList(0) _ ,80) _ , AddressOf EndConnect _ , State) End Sub Public Sub EndConnect(AR as System.IAsyncResult) mySocket.EndConnect(AR) End Sub and now you are connected. so now that you are connected, you may want to allow the connection to recieve data. i generally stick this in another function and call it right after the client connects or the session accepts. it looks like this: Public Sub Recieve() Dim State as New StateObject() mySocket.BeginReceive(State.Buffer _ , 0 _ , State.Size _ , System.Net.Sockets.SocketFlags.None _ , addressof EndReceive _ , State) End Sub Public Sub EndReceive(AR as IAsyncResult) Dim State as StateObject = ctype(AR, StateObject) Dim Length as Integer = mySocket.EndReceive(AR) System.Diagnostics.Debug.WriteLine(System.Text.Encoding.ASCII.GetString(State.Buffer, 0, Length)) Receive() ' call this to set up receiving again. End Sub if that works, we should receive data and debug should display it whenever the server sends us something. now, to send data! Public Sub Send(Data() as Byte) Dim State as New StateObject() mySocket.BeginSend(Data, 0, Data.Length, Sockets.SocketFlags.None, addressof EndSend, State) End Sub Public Sub EndSend(AR as IAsyncResult) Dim Length as Integer Length = mySocket.EndSend(AR) System.Diagnostics.Debug.WriteLine("Sent: " & Length.ToString()) End Sub so, if we connect to www.google.com on port 80, and do the following: Send("GET / HTTP/1.1" & vbNewLine & "Host: www.google.com" & vbNewLine & vbNewLine)
we SHOULD get a web page back. please note, i have typed all of this in this text box, so theres a slight chance i might have made a typo somewhere. [edit] Serverwhew! now that was pretty much the hard part. (error handling is a bit harder) but on to some easy stuff. servers pretty much just listen for a connection, and then once a connection is requested, it passes the socket on to a session. (yes, you can combine all of this into one socket like the winsock control from vb6, but its easier to break them down into 3 components) how to open a connection: Public Sub Listen(Port as Integer, Backlog as Integer) mySocket.Bind(System.Net.IPAddress.Any, Port) mySocket.Listen(Backlog) mySocket.BeginAccept(AddressOf Request, mySocket) End Sub Public Sub Request(AR as IAsyncResult) System.Diagnostics.Debug.Writeline("Connection Requested.") ' Accept(AR) ' use this with sessions mySocket.BeginAccept(AddressOf Request, mySocket) End Sub note the function "Accept" this will be used with sessions to accept a connection. [edit] SessionsNow, server and session sockets go hand in hand. servers listen while sessions accept. the purpose of this is so you can just have one server listening, and array of sessions to work with. heres how to accept a connection with a session: Public Sub Accept(AR as IAsyncResult) Dim pSocket as System.Net.Sockets.Socket = ctype(AR.AsyncState, System.Net.Sockets.Socket) mySocket = pSocket.EndAccept(AR) ' here you would want to start recieving also End Sub and thats pretty much it. [edit] CommentsThis is my first tutorial that ive tried to write, and i am willing to admit, its probably hard to understand at first. if you have any questions, just email me. this should be open to people to edit also, i have no problems with that, or else i wouldnt have been posting this here =P [edit] ResourcesLidgren.Library.Network (Network library for Reliable UDP in C#) |


