Jump to content

tcp socket server application

- - - - -

  • Please log in to reply
3 replies to this topic

#1
santhosh89

santhosh89

    Newbie

  • Members
  • Pip
  • 2 posts
Guys,

I am trying to create a GUI socket server.

The goal is simple.

1.Open a port
2.keep sending data to the port
3.the data is given from a textbox in the gui and must be sent after the button is pressed.
4.Do NOT CLOSE THE CONNECTION to the port until a button is pressed in the GUI.

I have done some part of it but the problem i m facing with my code is i am not able to split the accept client connection part from the send data to client part.

Hence each time i click my button to send the data i have to close the connection and open a new connection again. Please help me with this. The code below executes on button press. As you can see each time i have to close the socket and redo everything on each button press. I am not able to split it into parts. Please help me.


 Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);


IPEndPoint ip = new IPEndPoint(IPAddress.Any, 9999);

            

            socket.Bind(ip);

            socket.Listen(10);

            Console.WriteLine("Waiting for a client...");


Socket client = socket.Accept();

            IPEndPoint clientep = (IPEndPoint)client.RemoteEndPoint;

            cliStatusLbl.Text = "Connected with Client";

           

          

                string sndCmd = "|" + this.keyTxt + "|" + this.valTxt + "\n";

               

                byte[] data = new byte[1024];

                data = Encoding.ASCII.GetBytes(sndCmd);

               

                client.Send(data, data.Length, SocketFlags.None);

                Thread.Sleep(2000);

            

            client.Close();

            socket.Close();


#2
sam_coder

sam_coder

    Programming Expert

  • Members
  • PipPipPipPipPipPip
  • 372 posts
So, the basic idea is to create the socket, much like you're doing, but you want to accept connections asynchronously.
I assume from your description, that you basically want to have the server periodically send data to all clients that are connected,
the data is the text from a text box, and will be sent out whenever you hit a button.

First of all, you need to decide what a client is. From the server's perspective. You might make a class like this,

class ClientState {

   public Socket ClientSocket { get; set; }

   public byte[] frame_buffer;

   public MemoryStream RecieveBuffer;

}


The idea, is that once you set up your server Listener. I'll use your example as best as possible. This is just pseudo code for explanation though


static Socket socket;


private listen() {

    socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

    IPEndPoint ep_local = new IPEndPoint(IPAddress.Any, 9999);

    socket.Bind(ip);

    socket.Listen(4); //don't set this to 10

    Console.WriteLine("Waiting for clients");

    socket.BeginAccept(on_accept, null);

}



private on_accept(IAsyncResult result) {

   Socket client_socket = socket.EndAccept(result);

   ClientState cs = new ClientState();

   cs.ClientSocket = client_socket;

   cs.frame_bufer = new byte[1024];

   cs.RecieveBuffer = new MemoryStream();


   cs.ClientSocket.BeginRecieve(cs.frame_buffer, 0, frame_buffer.Length, SocketFlags.None, on_recieve, cs);


}                      


private on_recieve(IAsyncResult result) {

    ClientState client = (ClientState)result.AsyncState;

    int recv = client.ClientSocket.EndRecieve(result);

    cs.RecieveBuffer.Write(cs.frame_buffer, 0, recv);

    cs.ClientSocket.BeginRecieve(cs.frame_buffer, 0, frame_buffer.Length, SocketFlags.None, on_recieve, cs);


    //depending on your application protocol, here is possibly where you would extract messages out of your receive buffer, 

    // the idea would be to take a message out, and raise an event or something with it, and then clear out the message, leaving whatever else is in that buffer,

    // because it might be part of the next message right?


}



So at this point, you now basically have a two way channel with that client right? (well really we've wired up the server to accept incoming data from the clients, you'd need to wire up the client application as well)

if you were to stick the ClientStates in a collection of some sort, you could easily reference them to send them information whenever you wanted. Like if you hit a send button, you could do this...



foreach (ClientState client in Clients) {

    Send(client, "message");

}



assuming you had a method called Send, that took a client state, and then sent the message in the usual ways.


Be careful with this, this is just me talking for a starting point. There is a lot wrong with this really, and wouldnt be the type of code you would trust in a production environment.


Anyways,

#3
santhosh89

santhosh89

    Newbie

  • Members
  • Pip
  • 2 posts
sam_coder

thank you for your response, But since it was urgent for me i did a little more digging and found an other tcp tutorial that helped me. What i did is create a multi threaded tcp server which has one thread listening for incoming calls fromo clients infinitely and once a client connects i create an instance for the client and add it to an hashtable. Now the GUI thread will have the necessary textbox and buttons and each time user clicks the button i loop over the hashtable and send the data easly to the connected clients through their instances from the hash table. There is also another thread to listen for disconnections and remove the appropriate objects from the hashtable.

#4
sam_coder

sam_coder

    Programming Expert

  • Members
  • PipPipPipPipPipPip
  • 372 posts
Ah right on! Glad you're all set up!




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users