C# TCP Server cannot response to client - c#

So my job now is to create a server that can respond and connect to several client at once, that's why I create a threaded server and some test client to check.
The Client can connect to the server them by pressing a button, it will send a message to the server, the server will put to message to its interface then respond to the client. Lastly the client will receive the response and put it onto its interface.
The problem I got now is the server can receive the message from the server and display but the response from server to client is not successful even though they are similar. From the debugger it seems that the client is stuck at the Read procedure.
Below is my code for the server. I think the problem come at the connection handler and client side. I am stuck now, please show me what did I do wrong ##
public class Server
{
TcpListener serverSocket = new TcpListener(IPAddress.Any, 3000);
TcpClient clientSocket = default(TcpClient);
int counter = 0;
private exampleCallback callback;
public Server(exampleCallback Callback)
{
callback = Callback;
}
public void initServer()
{
serverSocket.Start();
//Call back to main thread to update display
if (callback != null)
callback(">> Server Initialized!");
Console.WriteLine(">> Server Initialized!");
}
public void waitConnection()
{
int counter = 0;
while (true)
{
counter += 1;
clientSocket = serverSocket.AcceptTcpClient();
if (callback != null)
callback(">> Client number: " + counter + " started!");
Console.WriteLine(">> Client number: " + counter + " started!");
handleClient handerler = new handleClient(new exampleCallback(receiveCallback), clientSocket, counter);
Thread clientThread = new Thread(new ThreadStart(handerler.startConv));
clientThread.Start();
}
}
public void closeServer()
{
clientSocket.Close();
serverSocket.Stop();
}
private void receiveCallback(string message)
{
callback(message);
}
}
The code for Connection Handerler:
public class handleClient
{
private exampleCallback callback2;
TcpClient clientSocket;
int clientNo;
public handleClient(exampleCallback Callback, TcpClient client, int clNo)
{
callback2 = Callback;
clientSocket = client;
clientNo = clNo;
}
public void startConv()
{
int requestCount = 0;
byte[] byteFrom = new byte[10025];
string XMLfromClient = null;
string dataFromClient = null;
string serverResponse = null;
string serverXMLResponse = null;
NetworkStream serverStream = clientSocket.GetStream();
requestCount = 0;
while (true)
{
try
{
requestCount++;
//Receive requerst from client
serverStream.Read(byteFrom, 0, (int)clientSocket.ReceiveBufferSize);
XMLfromClient = System.Text.Encoding.ASCII.GetString(byteFrom);
callback2("\n >> From Client :" + clientNo + ". Message: \n" + XMLfromClient);
//Console.WriteLine(">> From Client :" + clientNo + ". Message: \n" + XMLfromClient);
//Send acknowledgement to client
serverResponse = "Server to Client(" + clientNo + "). Request time: " + requestCount;
byte[] byteTo = Encoding.ASCII.GetBytes(serverResponse);
serverStream.Write(byteTo, 0, byteTo.Length);
serverStream.Flush();
Console.WriteLine(">> " + serverResponse);
}
catch (Exception ex)
{
callback2(ex.ToString());
}
}
}
}
And lastly is the code for client size:
public partial class Form1 : Form
{
System.Net.Sockets.TcpClient clientSocket = new System.Net.Sockets.TcpClient();
NetworkStream serverStream;
public Form1()
{
InitializeComponent();
}
public void msg(string mesg)
{
this.Display.Text += Environment.NewLine + " >> " + mesg;
}
private void SendButton_Click(object sender, EventArgs e)
{
serverStream = clientSocket.GetStream();
byte[] outStream = System.Text.Encoding.ASCII.GetBytes("World Domination");
serverStream.Write(outStream, 0, outStream.Length);
serverStream.Flush();
Thread receive = new Thread(new ThreadStart(ReceiveMess));
}
private void ReceiveMess()
{
serverStream = clientSocket.GetStream();
byte[] inStream = new byte[10025];
serverStream.Read(inStream, 0, (int)clientSocket.ReceiveBufferSize);
string returndata = System.Text.Encoding.ASCII.GetString(inStream);
msg("Data from Server : " + returndata);
}
private void connectButton_Click(object sender, EventArgs e)
{
msg("Client Started");
clientSocket.Connect("127.0.0.1", 3000);
this.Display.Text = "Client Socket Program - Server Connected ...";
}
}

You seem to forget to start the receive thread:
private void SendButton_Click(object sender, EventArgs e)
{
// ... skipped .........
Thread receive = new Thread(new ThreadStart(ReceiveMess));
receive.Start(); // <--- try adding this line
}

server will put to message to its interface then respond to the client
So the server is a GUI app?
Based on the code you appear to have blocking operations (eg. AcceptTcpClient) on the GUI thread. This is going to fail. The GUI thread will block (and the UI will be unresponsive), which means updates to the IO from workers will block waiting on the UI (all UI operations must happen on the main thread).
Additionally spinning up a new thread for each connection is a bad idea. Threads are expensive.
You need to rewrite from the start (both client and server).
Avoid blocking operations (even file IO if you want maximum performance) on the GUI thread/
All socket operations should be run in the thread pool (let the system manage the threads for you).
Avoid waiting on the GUI from background threads (prefer BeginInvoke over Invoke).
Even better would be to use async: the system will manage the thread switching for you.

Related

TCPListener in windows form

I am trying to write a TCP listener that can connect to multiple clients and send and receive data.
Some of my code -
Calling server -
private void Form1_Load(object sender, EventArgs e)
{
// TODO: This line of code loads data into the 'cresijCamDataSet1.CentralControl' table. You can move, or remove it, as needed.
this.centralControlTableAdapter1.Fill(this.cresijCamDataSet1.CentralControl);
s = new Server();
Thread th = new Thread(s.Run);
th.Start();
}
Run Method -
public async void Run()
{
tcp = new TcpListener(IPAddress.Any, 1200);
tcp.Start();
while (true)
{
try
{
TcpClient client = await tcp.AcceptTcpClientAsync();
Thread th = new Thread(()=>{
Process(client);
}) ;
}
catch (Exception ex)
{
string m = ex.Message;
}
}
}
private async Task Process(TcpClient tcpClient)
{
bool hasItem = clients.Contains(tcpClient);
if(hasItem == false)
{
clients.Add(tcpClient);
}
IPEndPoint iPEndPoint =(IPEndPoint) tcpClient.Client.RemoteEndPoint;
string ip = ((IPEndPoint)tcpClient.Client.RemoteEndPoint).Address.ToString();
NetworkStream stream = tcpClient.GetStream();
byte[] receivedBytes = new byte[tcpClient.ReceiveBufferSize];
stream.Read(receivedBytes, 0, receivedBytes.Length);
f.UpdateData(receivedBytes, ip);
}
Sender Method to send data -
public void Sender(byte[] data, TcpClient client)
{
NetworkStream stream = client.GetStream();
stream.Write(data, 0, data.Length);
}
As you can see I have called Run() method in formLoad. But this all is not working as I dont have much knowledge of threads.
This method is not continuous. The server is not listening to clients always. Can someone help me with this. I need asynchronuous tcp listener that can listen to incoming clients and that too in windows form. Console Server I have.

tcplistener and client in same Forms app

I have this code that seems to stop working at Socket client = listener.AcceptSocket();
This code works fine in a console app but when I try to use it in a windows forms app it doesn't start / the windows doesn't show up
Here is my code:
public Form1()
{
InitializeComponent();
Listen();
}
public void Listen()
{
try
{
IPAddress ipAddress = IPAddress.Parse("127.0.0.1");
Console.WriteLine("Starting TCP listener...");
TcpListener listener = new TcpListener(ipAddress, 1302);
listener.Start();
while (true)
{
Console.WriteLine("Server is listening on " + listener.LocalEndpoint);
Console.WriteLine("Waiting for a connection...");
Socket client = listener.AcceptSocket(); // <----- PROBLEM
Console.WriteLine("Connection accepted.");
Console.WriteLine("Reading data...");
byte[] data = new byte[100];
int size = client.Receive(data);
Console.WriteLine("Recieved data: ");
for (int i = 0; i < size; i++)
Console.Write(Convert.ToChar(data[i]));
Console.WriteLine();
client.Close();
}
listener.Stop();
}
catch (Exception e)
{
Console.WriteLine("Error: " + e.StackTrace);
Console.ReadLine();
}
}
private void button1_Click(object sender, EventArgs e)
{
if (richTextBox1.Text != "")
{
textToSend = richTextBox1.Text;
run = true;
}
else
{
MessageBox.Show("Box Cant Be Empty");
run = false;
}
if (run)
{
try
{
TCPclient = new TcpClient(SERVER_IP, PORT_NO);
nwStream = TCPclient.GetStream();
}
catch
{
}
byte[] bytesToSend = ASCIIEncoding.ASCII.GetBytes(textToSend);
//---send the text---
MessageBox.Show("Sending : " + textToSend);
nwStream.Write(bytesToSend, 0, bytesToSend.Length);
}
}
The console will continue to output even when the code that is running is busy. It is painted outside of your application.
The windows form you are using needs the main application thread to be available for it to update and paint the form. You should look up the async / await pattern and learn to use it for blocking IO calls. The topic is too big to give you a simple quick answer, but you can find some information on async / await here: https://msdn.microsoft.com/library/hh191443(vs.110).aspx though there may be better articles to be found with some googlefu.
Some additional information can be found here about UI responsiveness:
https://msdn.microsoft.com/en-us/library/windows/desktop/dd744765(v=vs.85).aspx
Socket client = listener.AcceptSocket(); is waiting for an incoming packet. Unless and until it receives one, WinForm UI won't show up, as you are calling Listen(); in the form constructor, thus blocking the Main Thread(UI).
Run Listen(); in a separate thread.

I have a server application that gets data exactly half the time. Why/how does this happen and how do I fix it?

So my server and chat client are made from 2 different C# TCP tutorials.You may recognize 1 if not both of them and I have made my own modifications to them to fit my own style. When I tried both they worked perfectly fine with 0 loss, but my version has exactly a 50% loss rate.
For instance:
1. A client connects: Data received
2. A client sends text: No Data
3. A client sends text: Data received
4. A client sends text: No Data
The server code is as follows:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Threading;
using System.Net;
namespace WindowsFormsApplication2
{
class Server
{
private TcpListener tcpListener;
private Thread listenThread;
public Hashtable clientsList = new Hashtable();
private System.Windows.Forms.TextBox output;
private delegate void ObjectDelegate(String text);
private ObjectDelegate del;
public Server(System.Windows.Forms.TextBox setOut)
{
this.tcpListener = new TcpListener(IPAddress.Any, 8888);
this.listenThread = new Thread(new ThreadStart(ListenForClients));
this.listenThread.IsBackground = true;
this.listenThread.Start();
output = setOut;
del = new ObjectDelegate(outputTextToServer);
}
private void ListenForClients()
{
this.tcpListener.Start();
while (true)
{
//blocks until a client has connected to the server
TcpClient client = this.tcpListener.AcceptTcpClient();
//create a thread to handle communication
//with connected client
addClient(client);
Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm));
clientThread.IsBackground = true;
clientThread.Start(client);
}
}
private void HandleClientComm(object client)
{
TcpClient tcpClient = (TcpClient)client;
NetworkStream clientStream = tcpClient.GetStream();
byte[] message = new byte[4096];
int bytesRead;
while (true)
{
bytesRead = 0;
try
{
//blocks until a client sends a message
bytesRead = clientStream.Read(message, 0, 4096);
}
catch
{
//a socket error has occured
break;
}
if (bytesRead == 0)
{
//the client has disconnected from the server
break;
}
//message has successfully been received
String text = getData(clientStream);
del.Invoke(text); //Used for Cross Threading & sending text to server output
//if filter(text)
sendMessage(tcpClient);
//System.Diagnostics.Debug.WriteLine(text); //Spit it out in the console
}
tcpClient.Close();
}
private void outputTextToServer(String text)
{
if (output.InvokeRequired)
{
// we then create the delegate again
// if you've made it global then you won't need to do this
ObjectDelegate method = new ObjectDelegate(outputTextToServer);
// we then simply invoke it and return
output.Invoke(method, text);
return;
}
output.AppendText(Environment.NewLine + " >> " + text);
}
private String getData(NetworkStream stream)
{
int newData;
byte[] message = new byte[4096];
ASCIIEncoding encoder = new ASCIIEncoding();
newData = stream.Read(message, 0, 4096);
String text = encoder.GetString(message, 0, newData); //Translate it into text
text = text.Substring(0, text.IndexOf("$")); //Here comes the money
return text;
}
private void addClient(object client)
{
TcpClient tcpClient = (TcpClient)client;
NetworkStream clientStream = tcpClient.GetStream();
String dataFromClient = getData(clientStream);
if (clientsList.Contains(dataFromClient))
{
Console.WriteLine(dataFromClient + " Tried to join chat room, but " + dataFromClient + " is already in use");
//broadcast("A doppleganger of " + dataFromClient + " has attempted to join!", dataFromClient, false);
}
else
{
clientsList.Add(dataFromClient, tcpClient);
//broadcast(dataFromClient + " Joined ", dataFromClient, false);
del.Invoke(dataFromClient + " Joined chat room ");
//handleClinet client = new handleClinet();
//client.startClient(clientSocket, dataFromClient, clientsList);
}
}
private Boolean connectionAlive(NetworkStream stream)
{
byte[] message = new byte[4096];
int bytesRead = 0;
try
{
//blocks until a client sends a message
bytesRead = stream.Read(message, 0, 4096);
}
catch
{
//a socket error has occured
return false;
}
if (bytesRead == 0)
{
//the client has disconnected from the server
//clientsList.Remove
return false;
}
return true;
}
private void sendMessage(TcpClient client)
{
NetworkStream clientStream = client.GetStream();
ASCIIEncoding encoder = new ASCIIEncoding();
byte[] buffer = encoder.GetBytes("Hello Client!");
clientStream.Write(buffer, 0, buffer.Length);
clientStream.Flush();
}
}
}
And here's my client code
using System;
using System.Windows.Forms;
using System.Text;
using System.Net.Sockets;
using System.Threading;
namespace WindowsFormsApplication2
{
public partial class Form1 : Form
{
public delegate void newDelegate();
public newDelegate myDelegate;
System.Net.Sockets.TcpClient clientSocket = new System.Net.Sockets.TcpClient();
NetworkStream serverStream = default(NetworkStream);
string readData = null;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
newMsg();
}
private void newMsg()
{
byte[] outStream = System.Text.Encoding.ASCII.GetBytes(textBox2.Text + "$");
serverStream.Write(outStream, 0, outStream.Length);
serverStream.Flush();
textBox2.Text = "";
}
private void button2_Click(object sender, EventArgs e)
{
readData = "Connecting to Chat Server ...";
msg();
clientSocket.Connect(txtIP.Text, int.Parse(txtPort.Text));
serverStream = clientSocket.GetStream();
byte[] outStream = System.Text.Encoding.ASCII.GetBytes(txtName.Text + "$");
serverStream.Write(outStream, 0, outStream.Length);
serverStream.Flush();
myDelegate = new newDelegate(disconnect);
Thread ctThread = new Thread(getMessage);
ctThread.IsBackground = true;
ctThread.Start();
button2.Enabled = false;
}
private void getMessage()
{
while (true)
{
serverStream = clientSocket.GetStream();
int buffSize = 0;
byte[] inStream = new byte[clientSocket.ReceiveBufferSize];
buffSize = clientSocket.ReceiveBufferSize;
try
{
serverStream.Read(inStream, 0, buffSize);
string returndata = System.Text.Encoding.ASCII.GetString(inStream);
readData = "" + returndata;
msg();
}
catch
{
Invoke(myDelegate);
return;
}
}
}
private void disconnect()
{
button2.Enabled = true;
}
private void msg()
{
if (this.InvokeRequired)
this.Invoke(new MethodInvoker(msg));
else
textBox1.AppendText(Environment.NewLine + " >> " + readData);
//textBox1.Text = textBox1.Text + Environment.NewLine + " >> " + readData;
}
private void textBox2_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
newMsg();
}
}
private void cmdHost_Click(object sender, EventArgs e)
{
Server serv = new Server(txtLog);
}
}
}
This code is obviously a work in progress and sorry in advance for messiness. Any other suggestions to the code are also welcome.
Okay, this is starting to get a bit long.
There's multiple errors in your code. Starting with the server code:
As Damien noted, you're trying to read each "message" twice - first in HandleClientComm, then again in getData. The stream no longer has the original data, so you're just throwing one of the reads away completely (thus the suspicious 50% "packet" loss)
Later, in getData, you discard all the data in the stream after the first $. While this is obviously an attempt at handling message framing (since TCP is a stream-based protocol, not a message-based protocol), it's a silly one - you're throwing the data away. The reason this didn't show in your testing is that 1) Windows treats local TCP very differently from remote TCP, 2) You'd need to be actually able to send two messages fast enough to make them "blend" together in the stream. That means either sending two messages in about 200ms (default TCP buffering) or blocking on reads.
You keep Flushing the network stream. This doesn't actually do anything, and even if it did, you wouldn't want to do that.
connectionAlive reads from the shared socket - this is always a bad idea. Never have more than one reader - multiple readers don't work with stream-based protocols. It doesn't seem you're using it in your sample code, but beware of trying to.
The commented out clientList.Remove would of course be a cross-thread access of a shared field. If you want to do it like this, you'll have to ensure the concurrent access is safe - either by using ConcurrentDictionary instead of HashSet, or by locking around each write and read of clientList.
You're expecting to get the whole message in one Read. That may be fine for a simple chat client, but it's bad TCP anyway - you need to read until you find your message terminator. If I send a message big enough, your code will just drop dead on text.IndexOf("$").
There's a lot of "style" issues as well, although this isn't code review, so let me just list some: using ancient technology, synchronous sockets for the server, mixing multi-threaded code with GUI at will. This is mostly about maintainability and performance, though - not correctness.
Now, the client is a bit simpler:
Again, don't Flush the network stream.
Don't use background threads if you don't have to. Simply make sure to terminate the connections etc. properly.
Disconnect should actually disconnect. It's not that hard, just close the TcpClient.
What is readData = "" + returndata supposed to do? That's just silly.
You're ignoring the return value of Read. This means that you have no idea how many bytes of data you read - which means your returnData string actually contains the message followed by a few thousand \0 characters. The only reason you don't see them in output is because most of Windows uses \0 as the string terminator ("it made sense at the time"). .NET doesn't.
Again, the Read expects the whole message at once. Unlike the server, this isn't going to crash the client, but your code will behave differently (e.g. an extra \r\n >> even though it's not a separate message.
The style issues from the server also apply here.
As a side-note, I've recently made a simplified networking sample that handles a simple chat client-server system using more modern technologies - using await-based asynchronous I/O instead of multi-threading, for example. It's not production-ready code, but it should show the ideas and intent quite clearly (I also recommend having a look at the first sample, "HTTP-like TCP communication"). You can find the full source code here - Networking Part 2.

send data to any connected client

I have created server application to accept connection from clients. After client connected to server ... they can send data and receive data between each other , but when another client is connected ... the server can not send data to frist client connected .
I need help how to save connected client on this server ... and how to send data to specified client.
The server class is :
namespace WindowsApplication11
{
public partial class Form1 : Form
{
private TcpListener tcpListener;
private Thread listenThread;
public Form1()
{
InitializeComponent();
}
TcpListener myList;
private void Form1_Load(object sender, EventArgs e)
{
try
{
myList = new TcpListener(IPAddress.Any, 8001);
/* Start Listeneting at the specified port */
myList.Start();
while (true)
{
TcpClient client = myList.AcceptTcpClient();
saveclient(" Client " + client.Client.RemoteEndPoint.ToString());
// - receive msg from client -
byte[] bb = new byte[10000];
int kb = client.Client.Receive(bb);
string stringu = "";
for (int i = 0; i < kb; i++)
stringu += Convert.ToChar(bb[i]);
// - send msg to accepted client -
Byte[] datat = System.Text.Encoding.ASCII.GetBytes("nje-> " + stringu);
NetworkStream stream = client.GetStream();
stream.Write(datat, 0, datat.Length);
stream.Flush();
}
}
catch (Exception ea)
{
Console.WriteLine("Error..... " + ea.Message);
}
}
void saveclient(string idlidhje)
{
try
{
System.IO.StreamWriter stw = System.IO.File.AppendText("d:\\clients.txt");
string teksti = System.String.Format("{0:G}: {1}.", System.DateTime.Now, idlidhje);
stw.WriteLine(teksti + "\n");
stw.Close();
}
catch (Exception eks)
{
}
}
}
}
The client class is :
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
IPAddress addr = IPAddress.Any;
byte[] data = new byte[1024];
string input, stringData;
TcpClient server;
try
{
server = new TcpClient("127.0.0.1", 8001);
// - send msg -
Byte[] datat = System.Text.Encoding.ASCII.GetBytes("Hello");
NetworkStream stream = server.GetStream();
stream.Write(datat, 0, datat.Length);
stream.Flush();
// - receive msg -
byte[] bb = new byte[10000];
int kb = server.Client.Receive(bb);
string stringu = "";
for (int i = 0; i < kb; i++)
stringu += Convert.ToChar(bb[i]);
}
catch (SocketException fd)
{
MessageBox.Show("Cannot connect " + fd.Message.ToString());
}
}
Robert answered to a similar question here on SO:
https://stackoverflow.com/a/15878306/17646
Basically you have to keep the connected clients in a list (your TcpClient object 'client' gets lost every time the while loop starts again) and you need threads or async methods to handle the different clients.

How would I constant listen on a port with a GUI?

I am trying to learn TCP server/client interaction. I want to know how I would listen to a port all the time with GUI. Currently I am using this code:
private void Form1_Load(object sender, EventArgs e)
{
CreateServer();
}
void CreateServer()
{
TcpListener tcp = new TcpListener(25565);
tcp.Start();
Thread t = new Thread(() =>
{
while (true)
{
var tcpClient = tcp.AcceptTcpClient();
ThreadPool.QueueUserWorkItem((_) =>
{
Socket s = tcp.AcceptSocket();
console.Invoke((MethodInvoker)delegate { console.Text += "Connection esatblished: " + s.RemoteEndPoint + Environment.NewLine; });
byte[] b = new byte[100];
int k = s.Receive(b);
for (int i = 0; i < k; i++)
{
console.Text += Convert.ToChar(b[i]);
incoming += Convert.ToChar(b[i]);
}
MessageBox.Show(incoming);
console.Invoke((MethodInvoker)delegate { console.Text += incoming + Environment.NewLine; });
list.Invoke((MethodInvoker)delegate { list.Items.Add(incoming); });
ASCIIEncoding asen = new ASCIIEncoding();
s.Send(asen.GetBytes("\n"));
tcpClient.Close();
}, null);
}
});
t.IsBackground = true;
t.Start();
}
Any help would be much appreciateed.
Short answer - run TCP listener in the separate Thread/Task (TPL).
For full working solution you also have to implement dispatching of the any changes to UI form separate thread to main thread using special technique which is depends on Framework you are using, I mean WPF/WinForms/whatever.
Code below works for me fine. Read TODO section before.
TODO:
Add to form Textbox, ListBox, Button, make public:
public System.Windows.Forms.TextBox console;
public System.Windows.Forms.ListBox incommingMessages;
private System.Windows.Forms.Button sendSampleDataButton;
Entry point:
private static Form1 form;
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
form = new Form1();
form.Load += OnFormLoad;
Application.Run(form);
}
private static void OnFormLoad(object sender, EventArgs e)
{
CreateServer();
}
Server:
private static void CreateServer()
{
var tcp = new TcpListener(IPAddress.Any, 25565);
tcp.Start();
var listeningThread = new Thread(() =>
{
while (true)
{
var tcpClient = tcp.AcceptTcpClient();
ThreadPool.QueueUserWorkItem(param =>
{
NetworkStream stream = tcpClient.GetStream();
string incomming;
byte[] bytes = new byte[1024];
int i = stream.Read(bytes, 0, bytes.Length);
incomming = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
form.console.Invoke(
(MethodInvoker)delegate
{
form.console.Text += String.Format(
"{0} Connection esatblished: {1}{2}",
DateTime.Now,
tcpClient.Client.RemoteEndPoint,
Environment.NewLine);
});
MessageBox.Show(String.Format("Received: {0}", incomming));
form.incommingMessages.Invoke((MethodInvoker)(() => form.incommingMessages.Items.Add(incomming)));
tcpClient.Close();
}, null);
}
});
listeningThread.IsBackground = true;
listeningThread.Start();
}
Client
private void button1_Click(object sender, EventArgs e)
{
Connect("localhost", "hello localhost " + Guid.NewGuid());
}
static void Connect(String server, String message)
{
try
{
Int32 port = 25565;
TcpClient client = new TcpClient(server, port);
Byte[] data = System.Text.Encoding.ASCII.GetBytes(message);
NetworkStream stream = client.GetStream();
// Send the message to the connected TcpServer.
stream.Write(data, 0, data.Length);
stream.Close();
client.Close();
}
catch (ArgumentNullException e)
{
Debug.WriteLine("ArgumentNullException: {0}", e);
}
catch (SocketException e)
{
Debug.WriteLine("SocketException: {0}", e);
}
}
Screenshot:
Create a thread, start to listen in it & don't stop the server
void CreateServer()
{
TcpListener tcp = new TcpListener(25565);
tcp.Start();
Thread t = new Thread(()=>
{
while (true)
{
var tcpClient = tcp.AcceptTcpClient();
ThreadPool.QueueUserWorkItem((_) =>
{
//Your server codes handling client's request.
//Don't access UI control directly here
//Use "Invoke" instead.
tcpClient.Close();
},null);
}
});
t.IsBackground = true;
t.Start();
}
You could use the threads approach (as mentioned by other answers) or use asynchronous sockets, which in my opnion is way better. And even better, you can use the async model proposed by SocketAsyncEventArgs.
Async sockets will take benefits from using completion ports.
here is a good example on mdsn: Asynchronous server socket example

Categories