By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
429,384 Members | 714 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 429,384 IT Pros & Developers. It's quick & easy.

multi client to server in C#

P: 33
Hi guys:
This topic might sound very familiar to some of you, can some one shed some light or point me to some web link for some sample code or good guide?

I'm able to code for a simple client to server ( one to one) but not this multi client scenario.

The application that i want to establish is simple:

clientx.1--------------> send a request to server for a job
clientx.2--------------> send a request to server for another job
..
....

all this activities have to be concurrent...

how to do this?


Thanks
Dec 7 '08 #1
Share this Question
Share on Google+
17 Replies


P: 61
@Jetean
Use ThreadPool wherein you can run your client(s) separately on thread(s).
ie clientx.1-> will run on Thread1
clientx.2-> will run on Thread2...
Dec 8 '08 #2

P: 33
Hi:

Are you suggesting to have multiple server running on multiple thread?

Is this viable?

Thanks
Dec 8 '08 #3

P: 61
@Jetean
No no... Its about client. You can have your client on a separate thread which communicates to the server. If you have common resources across the clients, you may have to opt synchronization between your clients.
Dec 8 '08 #4

Expert 100+
P: 190
Can you please clarify what design you are using for "client/server."
Are you using Remoting, WebServices, or hand-coded socket communication?

Are these truly separate clients talking to one server in a separately compiled server application or listener?

If so, what protocol do you use to send and receive job requests?

Mike
Dec 8 '08 #5

P: 33
OK. I'm using Socket. The application is to serve multiple PCs within the same office. 1 server and multiple clients. I think i can handle the client side but I'm not sure about the Server side program. How to do it?
Dec 8 '08 #6

P: 33
One more condition is that The Server has to continously scan for any new connection and new incoming request..
Dec 8 '08 #7

Expert 100+
P: 190
For the listener, I would suggest you start by studying the System.Net.Sockets.TcpListener class, as this will take care much of the infrastructure of listening for socket connection requests and reading them.
Dec 9 '08 #8

P: 33
mldisibio:
I'm looking at Asynchronous TCP Server. I'm not quite sure how to implement it. With many Clients sending data back to Server, Will one Client Keep Connected to the server preventing access from other Clients?
Dec 10 '08 #9

P: 61
Is it something like your TCP SERVER(which you will be developing) has to perform normal tasks(irrespective of the operations) along with SERVING YOUR CLIENTS(each client is a separate PC)! Are you seeking Asynchronus SERVER for this purpose?
Dec 10 '08 #10

Expert 10K+
P: 11,448
The 'de facto' way to do this is to run a simple loop that accepts new clients. Once accepted the new socket/client is passed to a new thread that serves the client through that socket. Once done, the thread simply dies. Shared resources should be synchronized among the several client serving threads.

kind regards,

Jos
Dec 10 '08 #11

Plater
Expert 5K+
P: 7,872
Jos is actually right (pause for recovery of blockbuster news).

Generally, you will have thread that sets up the listener socket, loops around accepting connections (syncronous or asyncronous), and starts a new thread for each new connection.
Thread loop should take steps to not be a busy loop.

Each of your spawned threads will handle interaction with the connected client.

This is similar to the way a webserver works.
Dec 10 '08 #12

P: 6
Expand|Select|Wrap|Line Numbers
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Windows.Forms;
  9.  
  10. using System.Net;
  11. using System.Net.Sockets;
  12. using System.Diagnostics;
  13.  
  14. using System.IO;
  15.  
  16. namespace Server
  17. {
  18.     public partial class ServerForm : Form
  19.     {
  20.         Dictionary<string, string> dictionary;
  21.  
  22.         const int BUFFER_SIZE = 1024;
  23.         byte[] rcvBuffer = new byte[BUFFER_SIZE];    // To recieve data from the client
  24.  
  25.         Socket serverSocket;
  26.         int socketCounter = 0;
  27.         Dictionary<Socket, int> clientSocketDictionary = new Dictionary<Socket, int>();
  28.  
  29.         const int PORT = 3333;
  30.  
  31.         public ServerForm()
  32.         {
  33.             InitializeComponent();
  34.             FillDictionary();
  35.             StartServer();
  36.         }
  37.  
  38.         //Construct server socket and bind it to all local netowrk interfaces, then listen for connections
  39.         void StartServer()
  40.         {
  41.             try
  42.             {
  43.                 serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  44.                 serverSocket.Bind(new IPEndPoint(IPAddress.Any, PORT));
  45.                 serverSocket.Listen(10);    // Listen(10) means we can handle
  46.                                             // 10 clients requests simultaneously
  47.                 serverSocket.BeginAccept(AcceptCallback, null);
  48.             }
  49.             catch (Exception ex) { AppendToTextBox(ex.Message); }
  50.         }
May 25 '14 #13

P: 6
you must determine the client ip first !
May 25 '14 #14

P: 6
Expand|Select|Wrap|Line Numbers
  1. void AcceptCallback(IAsyncResult AR)
  2.         {
  3.             try
  4.             {
  5.                 Socket tempSocket = serverSocket.EndAccept(AR);    // Client connected successfully, waiting for requests
  6.  
  7.                 tempSocket.BeginReceive(rcvBuffer, 0, rcvBuffer.Length, SocketFlags.None, ReceiveCallback, tempSocket);
  8.  
  9.                 socketCounter++;
  10.                 clientSocketDictionary.Add(tempSocket, socketCounter);
  11.  
  12.                 AppendToTextBox("Client " + socketCounter + " connected successfully...");
  13.  
  14.                 byte[] replyBuffer = Encoding.ASCII.GetBytes("Connected successfully...");
  15.                 tempSocket.Send(replyBuffer);
  16.  
  17.                 serverSocket.BeginAccept(AcceptCallback, null);
  18.             }
  19.  
  20.             catch (Exception ex) { AppendToTextBox(ex.Message); }
  21.         }
  22.  
  23.         void ReceiveCallback(IAsyncResult AR)
  24.         {
  25.             Socket tempSocket = (Socket)AR.AsyncState;
  26.             int bytesReceived = 0;
  27.             int clientNumber = clientSocketDictionary[tempSocket];
  28.  
  29.             try
  30.             {
  31.                 bytesReceived = tempSocket.EndReceive(AR);    // Get number of bytes received
  32.             }
  33.             catch (Exception ex)
  34.             {
  35.                 AppendToTextBox("Exception: " + ex.Message + "...");
  36.                 tempSocket.Close();
  37.                 clientSocketDictionary.Remove(tempSocket);
  38.             }
  39.  
  40.             if (bytesReceived > 0)
  41.             {
  42.                 byte[] rcvBufferTrim = new byte[bytesReceived];
  43.                 Array.Copy(rcvBuffer, rcvBufferTrim, bytesReceived);    // Removes trailing nulls
  44.                 string rcvText = Encoding.ASCII.GetString(rcvBufferTrim);    // Convert bytes into string
  45.                 rcvText = rcvText.ToLower().ToString();
  46.  
  47.                 string replyText = "";
  48.                 DateTime time = DateTime.Now;
  49.  
  50.                 #region Switch statement for received text, check for special requests
  51.                 switch (rcvText)
  52.                 {
  53.                     case "gettime":
  54.                         AppendToTextBox("Received from client [" + clientNumber.ToString() + "]: " + rcvText);
  55.                         replyText = "Time is : " + time.ToString("HH:MM:ss");
  56.                         break;
  57.                     case "getdate":
  58.                         AppendToTextBox("Received from client [" + clientNumber.ToString() + "]: " + rcvText);
  59.                         replyText = "Date is : " + time.ToString("dd/mm/yyyy");
  60.                         break;
  61.                     case "disconnect":
  62.                         tempSocket.Shutdown(SocketShutdown.Both);
  63.                         tempSocket.Close();
  64.                         clientSocketDictionary.Remove(tempSocket);
  65.                         AppendToTextBox("Client [" + clientNumber.ToString() + "] closed connection");
  66.                         return;
  67.                     default:
  68.                         AppendToTextBox("Received from client [" + clientNumber.ToString() + "]: " + rcvText);
  69.                         if (dictionary.ContainsKey(rcvText))
  70.                             replyText = dictionary[rcvText];
  71.                         else
  72.                             replyText = "Not Found";
  73.                         break;
  74.                 }
  75.                 #endregion
  76.  
  77.                 // Send the reply text
  78.                 byte[] replyBuffer = Encoding.ASCII.GetBytes(replyText);
  79.                 tempSocket.Send(replyBuffer);
  80.  
  81.                 // Starts receiving data again
  82.                 tempSocket.BeginReceive(rcvBuffer, 0, rcvBuffer.Length,
  83.                     SocketFlags.None, new AsyncCallback(ReceiveCallback), tempSocket);
  84.             }
  85.             else
  86.             {
  87.                 try
  88.                 {
  89.                     tempSocket.Shutdown(SocketShutdown.Both);
  90.                     tempSocket.Close();
  91.                     clientSocketDictionary.Remove(tempSocket);
  92.                     AppendToTextBox("Client [" + clientNumber.ToString() + "] closed connection");
  93.                 }
  94.                 catch { AppendToTextBox("Client [" + clientNumber.ToString() + "] closed connection"); }
  95.             }
  96.         }
  97.  
  98.         // Provides a thread-safe way to append text to the textbox
  99.         void AppendToTextBox(string text)
  100.         {
  101.             MethodInvoker invoker = new MethodInvoker(delegate
  102.             {
  103.                 textBox.Text += text + "\r\n";
  104.                 textBox.SelectionStart = textBox.TextLength;
  105.                 textBox.ScrollToCaret();
  106.             });    // "\r\n" are for new lines
  107.             this.Invoke(invoker);
  108.         }
  109.  
  110.         // Add all entries to fill the dictionary
  111.         void FillDictionary()
  112.         {
  113.             string[] lines = File.ReadAllLines("IPaddresses.txt");
  114.             dictionary = lines.Select(l => l.Split(':')).ToDictionary(a => a[0], a => a[1]);
  115.         }
  116.  
  117.         private void textBox_TextChanged(object sender, EventArgs e)
  118.         {
  119.  
  120.         }
  121.     }
  122. }
May 25 '14 #15

P: 6
this is the client code ! You can try it .
May 25 '14 #16

P: 6
Expand|Select|Wrap|Line Numbers
  1. namespace Client
  2. {
  3.     public partial class ClientForm : Form
  4.     {
  5.         const int BUFFER_SIZE = 1024;
  6.         byte[] sendBuffer = new byte[BUFFER_SIZE];
  7.  
  8.         byte[] rcvBuffer = new byte[BUFFER_SIZE];
  9.         Socket clientSocket;
  10.         const int PORT = 3333;
  11.  
  12.         public ClientForm()
  13.         {
  14.             InitializeComponent();
  15.         }
  16.  
  17.         void btnConnect_Click(object sender, EventArgs e)
  18.         {
  19.             string serverIP = "192.168.1.200";
  20.             try
  21.             {
  22.                 this.clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  23.                 // Connect to the local host
  24.                 clientSocket.Connect(new IPEndPoint(IPAddress.Parse(serverIP), PORT));
  25.                 // Prepares to receive something, i.e. the echo
  26.                 clientSocket.BeginReceive(rcvBuffer, 0, rcvBuffer.Length, SocketFlags.None, ReceiveCallback, null);
  27.                 EnableSendButton();
  28.             }
  29.             catch (Exception ex) { AppendToTextBox(ex.Message); }
  30.         }
  31.  
  32.         void btnSend_Click(object sender, EventArgs e)
  33.         {
  34.             try
  35.             {
  36.                 // Serialize the textBox text before sending
  37.                 sendBuffer = Encoding.ASCII.GetBytes(textBoxInput.Text);
  38.  
  39.                 // Sends contents of textbox to the server
  40.                 clientSocket.Send(sendBuffer);
  41.  
  42.                 // Prepares to receive something, i.e. the echo
  43.                 clientSocket.BeginReceive(rcvBuffer, 0, rcvBuffer.Length, SocketFlags.None, ReceiveCallback, null);//.Receive(rcvBuffer);
  44.             }
  45.             catch (Exception ex) { AppendToTextBox(ex.Message); }
  46.         }
  47.  
  48.         // About Asynchronous Callbacks: http://stackoverflow.com/questions/1...-asynccallback
  49.         void ReceiveCallback(IAsyncResult AR)
  50.         {
  51.             try
  52.             {
  53.                 int bytesReceived = clientSocket.EndReceive(AR);    // Number of bytes received
  54.                 if (bytesReceived == 0) return;
  55.                 byte[] rcvBufferTrim = new byte[bytesReceived];
  56.                 Array.Copy(rcvBuffer, rcvBufferTrim, bytesReceived);    // Removes trailing nulls
  57.                 string text = Encoding.ASCII.GetString(rcvBufferTrim);    // Convert bytes into string
  58.                 AppendToTextBox(DateTime.Now.ToString("HH:mm:ss") + ": " + text);        // Displays buffer contents as text
  59.  
  60.                 // Starts receiving data again
  61.                 clientSocket.BeginReceive(rcvBuffer, 0, rcvBuffer.Length, SocketFlags.None, ReceiveCallback, null);
  62.             }
  63.             catch (Exception ex) { AppendToTextBox(ex.Message); }
  64.         }
  65.  
  66.         // Provides a thread-safe way to enable the send button/disable the connect button
  67.         void EnableSendButton()
  68.         {
  69.             MethodInvoker invoker = new MethodInvoker(delegate
  70.             {
  71.                 btnSend.Enabled = true;
  72.                 btnConnect.Enabled = false;
  73.                 btnDisconnect.Enabled = true;
  74.                 textBoxInput.ReadOnly = false;
  75.                 btnDisconnect.Enabled = true;
  76.             });
  77.             this.Invoke(invoker);
  78.         }
  79.  
  80.         private void textBoxInput_KeyDown(object sender, KeyEventArgs e)
  81.         {
  82.             if (btnSend.Enabled == true
  83.                 && Control.ModifierKeys != Keys.Shift
  84.                 && e.KeyCode == Keys.Return)
  85.             {
  86.                 MethodInvoker invoker = new MethodInvoker(delegate { btnSend.PerformClick(); });
  87.                 this.Invoke(invoker);
  88.                 e.SuppressKeyPress = true;
  89.             }
  90.         }
  91.  
  92.         // Provides a thread-safe way to append text to the textbox
  93.         void AppendToTextBox(string text)
  94.         {
  95.             MethodInvoker invoker = new MethodInvoker(delegate
  96.             {
  97.                 textBoxDisplay.Text += text + "\r\n";
  98.                 textBoxDisplay.SelectionStart = textBoxDisplay.TextLength;
  99.                 textBoxDisplay.ScrollToCaret();
  100.             });    // "\r\n" are for new lines
  101.             try { this.Invoke(invoker); }
  102.             catch { };
  103.         }
  104.  
  105.         private void btnDisconnect_Click(object sender, EventArgs e)
  106.         {
  107.             sendBuffer = Encoding.ASCII.GetBytes("disconnect");
  108.             clientSocket.Send(sendBuffer);
  109.  
  110.             clientSocket.Shutdown(SocketShutdown.Both);
  111.             clientSocket.Close();
  112.  
  113.             this.Close(); // Close the window
  114.         }
  115.  
  116.         private void textBoxDisplay_TextChanged(object sender, EventArgs e)
  117.         {
  118.  
  119.         }
  120.     }
  121. }
May 25 '14 #17

P: 6
Don't forget this for client :

Expand|Select|Wrap|Line Numbers
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Windows.Forms;
  9.  
  10. using System.Net;
  11. using System.Net.Sockets;
May 25 '14 #18

Post your reply

Sign in to post your reply or Sign up for a free account.