TCPListener with multiple Clients - c#

I use layered architecture. I create a server. I want the server to listen when the data arrives.
This is my server code in the DataAccess layer.
public class ServerDal : IServerDal
{
private TcpListener server;
private TcpClient client = new TcpClient();
public bool ServerStart(NetStatus netStatus)
{
bool status = false;
try
{
server = new TcpListener(IPAddress.Parse(netStatus.IPAddress), netStatus.Port);
server.Start();
status = true;
}
catch (SocketException ex)
{
Console.WriteLine("Starting Server Error..." + ex);
status = false;
}
return status;
}
public string ReceiveAndSend(NetStatus netStatus)
{
Byte[] bytes = new Byte[1024];
String data = null;
Mutex mutex = new Mutex(false, "TcpIpReceive");
mutex.WaitOne();
if (!client.Connected)
client = server.AcceptTcpClient();
try
{
NetworkStream stream = client.GetStream();
int i;
if ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
{
data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
Console.WriteLine("Received: " + data);
}
}
catch (Exception ex)
{
Console.WriteLine("Connection Error..." + ex);
client.Close();
}
finally
{
mutex.ReleaseMutex();
}
return data;
}
}
I can listen to the client that first connects to the server. When the first connecting client disconnects, I can listen to the second connecting client.
I want to listen when both clients send data. How can I do that ? Thanks for your help.

I fixed the problem.
static List<TcpClient> tcpClients = new List<TcpClient>();
public void ReceiveMessage(NetStatus netStatus)
{
try {
TcpClient tcpClient = server.AcceptTcpClient();
tcpClients.Add(tcpClient);
Thread thread = new Thread(unused => ClientListener(tcpClient, netStatus));
thread.Start();
}
catch(Exception ex) {
Console.WriteLine("[ERROR...] Server Receive Error = {0} ", ex.Message);
}
}
public void ClientListener(object obj, NetStatus netStatus)
{
try
{
TcpClient tcpClient = (TcpClient)obj;
StreamReader reader = new StreamReader(tcpClient.GetStream());
while(true)
{
string message = null;
message = reader.ReadLine();
if(message!=null)
{
netStatus.IncommingMessage = message;
Console.WriteLine("[INFO....] Received Data = {0}", message);
}
}
}
catch(Exception ex)
{
Console.WriteLine("[ERROR....] ClientListener Error = {0}", ex.Message);
}
}

Related

Unable to read data from tcp server

I have created a simple C# client application. Once it connects to the server it should read the messages sent from the server. It also has the ability to send messages to server too. However I am unable to figure out to correct way to read the data.
I am spawning a thread once it connects to the server. The thread runs in infinite loop and have two interfaces each for reading and writing. Connect() method is called from a ButtonClick event.
My code snippet is as below:
namespace WpfApp1
{
public class TCPClientClass
{
private StreamWriter SwSender;
NetworkStream Sender;
NetworkStream Receiver;
//private StreamReader SrReciever;
private Thread thrMessaging;
TcpClient tcp;
bool connected = false;
public bool Connected { get { return connected; } set { connected = value; } }
//public bool Connect(IPAddress IP, int nPortNo)
public async Task Connect(IPAddress IP, int nPortNo)
{
tcp = new TcpClient();
try
{
//tcp.Connect(strIPAddress.Parse("192.168.137.1"), 2000);
// tcp.Connect(IP , nPortNo);
await tcp.ConnectAsync(IP, nPortNo);
thrMessaging = new Thread(new ThreadStart(ThreadFunction));
thrMessaging.Start();
Connected = true;
}
catch
{
MessageBox.Show("Unable to connect to server");
//return false;
}
//return true;
}
public void Disconnect()
{
Sender?.Close();
Receiver?.Close();
tcp?.Close();
//tcp?.Client.Disconnect(false);
thrMessaging.Abort();
Connected = false;
}
private void ThreadFunction()
{
while (thrMessaging.IsAlive)
DoTasks();
}
private void DoTasks()
{
if (Connected)
{
var a = ReadMessages();
SendMessages();
}
}
private /*void*/async Task ReadMessages()
{
byte[] data = new byte[4096];
//Int32 bytesRead = 0;
//Task<int> bytesReadTask;
String responseData = String.Empty;
Receiver = tcp.GetStream();
try
{
//bytesReadTask = Receiver.ReadAsync(data, 0, data.Length);
//responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytesReadTask.Result);
var response = await Receiver.ReadAsync(data, 0, data.Length);
MessageBox.Show("Server response was " + response);
Thread.Sleep(1000);
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
}
private void SendMessages()
{
try
{
string strSendData = "Hello from GUI";
Byte[] data = System.Text.Encoding.ASCII.GetBytes(strSendData);
Sender = tcp.GetStream();
Sender.Write(data, 0, data.Length);
Sender.Flush();
Thread.Sleep(1000);
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
}
}
}
you should change
var response = await Receiver.ReadAsync(data, 0, data.Length);
MessageBox.Show("Server response was " + response);
to
var response = await Receiver.ReadAsync(data, 0, data.Length);
string result = System.Text.Encoding.Default.GetString(data);
MessageBox.Show("Server response was " + result);
if you´re still having problems..my server Code:
public class tcpServer
{
public void method()
{
TcpListener server = new TcpListener(IPAddress.Any, 9999);
server.Start();
TcpClient client = server.AcceptTcpClient();
NetworkStream ns = client.GetStream();
byte[] hello = new byte[100];
hello = Encoding.Default.GetBytes("hello world");
while (client.Connected)
{
ns.Write(hello, 0, hello.Length);
}
}
}

clients cannot establish connection after certain time even if the socket server is running

I have a console application which acts as a socket server. It should accept data 24/7 from a number of clients, but issue is that the clients cannot establish connection after sometime (not constant). after closing & opening the connection works & it continues to next point of time.
Server
public static void ExecuteServer()
{
int portNumber = 11111;
string _responseMessageToClient = "";
IPHostEntry ipHost = Dns.GetHostEntry(Dns.GetHostName());
IPAddress ipAddr = ipHost.AddressList[0];
IPEndPoint localEndPoint = new IPEndPoint(ipAddr, portNumber);
// Creation TCP/IP Socket using
// Socket Class Costructor
Socket listener = new Socket(ipAddr.AddressFamily,
SocketType.Stream, ProtocolType.Tcp);
bool doBroadCast = false;
try
{
listener.Bind(localEndPoint);
listener.Listen(10);
while (true)
{
try`enter code here`
{
Socket clientSocket = listener.Accept();
// Data buffer
byte[] bytes = new Byte[1024*2];//2048
string data = null;
while (true)
{
try
{
if (clientSocket.Connected)
{
int numByte = clientSocket.Receive(bytes);
data += Encoding.ASCII.GetString(bytes,
0, numByte);
if (data.IndexOf("!") > -1)
break;
}
else
{
Console.WriteLine("Disconnected {0}", clientSocket.LocalEndPoint);
break;
}
}
catch (Exception e)
{
//ErrorLogProvider.Save(e);
Console.WriteLine(e.ToString());
break;
}
}
Console.WriteLine("Text received -> {0} ", data);
if (clientSocket.Connected)
{
clientSocket.Send(message);
}
clientSocket.Shutdown(SocketShutdown.Both);
clientSocket.Close();
}
catch (Exception e)
{
}
}
}
catch (Exception e)
{
}
}
This server has to be running continuously - Client code given below
static void ExecuteClient()
{
try
{
// Establish the remote endpoint
// for the socket. This example
// uses port 11111 on the local
// computer.
int portNumber = 11111;
IPHostEntry ipHost = Dns.GetHostEntry(Dns.GetHostName());
IPAddress ipAddr = ipHost.AddressList[0];
IPEndPoint localEndPoint = new IPEndPoint(ipAddr, portNumber);
// Creation TCP/IP Socket using
// Socket Class Costructor
Socket sender = new Socket(ipAddr.AddressFamily,
SocketType.Stream, ProtocolType.Tcp);
long i = 0;
try
{
//while (i < 10)
//{
// Connect Socket to the remote
// endpoint using method Connect()
sender.Connect(localEndPoint);
// We print EndPoint information
// that we are connected
Console.WriteLine("Socket connected to -> {0} ",
sender.RemoteEndPoint.ToString());
// Creation of messagge that
// we will send to Server
byte[] messageSent = Encoding.ASCII.GetBytes("^check!");
int byteSent = sender.Send(messageSent);
// Data buffer
byte[] messageReceived = new byte[1024];
// We receive the messagge using
// the method Receive(). This
// method returns number of bytes
// received, that we'll use to
// convert them to string
int byteRecv = sender.Receive(messageReceived);
Console.WriteLine("Message from Server -> {0}",
Encoding.ASCII.GetString(messageReceived,
0, byteRecv));
//}
// Close Socket using
// the method Close()
sender.Shutdown(SocketShutdown.Both);
sender.Close();
}
// Manage of Socket's Exceptions
catch (ArgumentNullException ane)
{
Console.WriteLine("ArgumentNullException : {0}", ane.ToString());
}
catch (SocketException se)
{
Console.WriteLine("SocketException : {0}", se.ToString());
}
catch (Exception e)
{
Console.WriteLine("Unexpected exception : {0}", e.ToString());
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
I've got this code somewhere from SO if I remember that correctly.
LoopClients just checks for new clients and handles them by spawning a new thread.
class Server {
private TcpListener _server;
private Boolean _isRunning = true;
private int m_Port = 12001;
private Thread m_ServerThread;
public Server (int p_Port) {
_server = new TcpListener(IPAddress.Any, m_Port);
_server.Start( );
m_ServerThread = new Thread(new ThreadStart(LoopClients));
m_ServerThread.Start( );
}
public void ShutdownServer() {
_isRunning = false;
}
public void LoopClients ( ) {
while ( _isRunning ) {
// wait for client connection
TcpClient newClient = _server.AcceptTcpClient( );
// client found.
// create a thread to handle communication
Thread t = new Thread(new ParameterizedThreadStart(HandleClient));
t.Start(newClient);
}
}
public void HandleClient (object obj) {
try {
// retrieve client from parameter passed to thread
TcpClient client = (TcpClient) obj;
// sets two streams
StreamWriter sWriter = new StreamWriter(client.GetStream( ), Encoding.ASCII);
StreamReader sReader = new StreamReader(client.GetStream( ), Encoding.ASCII);
// you could use the NetworkStream to read and write,
// but there is no forcing flush, even when requested
String sData = null;
while ( client.Connected ) {
sData = sReader.ReadToEnd( );
if ( sData != "" )
break;
}
try {
sWriter.WriteLine("test");
} catch(Exception ex) {
Console.WriteLine(ex.Message);
}
sWriter.Dispose( );
sReader.Dispose( );
sWriter = null;
sReader = null;
} catch ( IOException ioe ) {
}
}
}
Client is somewhat shorter. I've got to shorten the code a bit here.
Client:
private void sendDataViaTCP () {
TcpClient l_Client = new TcpClient();
l_Client.Connect(IP, Port);
Stream l_Stream = l_Client.GetStream( );
StreamWriter l_SW = new StreamWriter(l_Stream);
StreamReader l_SR = new StreamReader(l_SW.BaseStream);
try {
l_SW.WriteLine(Msg);
l_SW.Flush( );
String l_IncomingData;
while ( ( l_IncomingData = l_SR.ReadToEnd()) != "") {
AddLineToLog(l_IncomingData);
}
} finally {
l_SW.Close( );
}
}

TCP/IP listener variable byte length

I have a stream coming in that varies in length but has a start and stop character. When I run this code:
public TCPListener()
{
Int32 port = 31001;
IPAddress localAddr = IPAddress.Parse("192.168.0.78"); //Local
server = new TcpListener(localAddr, port);
server.Start();
while (true)
{
// Console.Write("Waiting for a connection...-- ");
TcpClient client = server.AcceptTcpClient();
// Console.WriteLine("new client connected");
try
{
ThreadPool.QueueUserWorkItem(new WaitCallback(HandleClient), client);
}
catch (Exception ex)
{ }
}
}
private void HandleClient(object tcpClient)
{
// string path = #"c:\Test.txt";
TcpClient client = (TcpClient)tcpClient;
Byte[] bytes = new Byte[135];
String data = null;
int i;
try
{
NetworkStream stream = client.GetStream();
while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
{
data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
URLObject oU = new URLObject();
oU = oDecode.TextFrameDecode(data);
Console.WriteLine(data);
Console.WriteLine("");
}
}
catch (Exception ex)
{ }
// Console.WriteLine(data);
}
I get a lot of data every second; I get the data, but it's broken up sometimes into chunks that are not parsable. When I run this code to look for the end delimiter, the feed only get one connection every couple of minutes with only one record so I think the data is getting truncated which is not correct.
static void Main(string[] args)
{
Int32 port = 31001;
IPAddress localAddr = IPAddress.Parse("192.168.0.78"); //Local
server = new TcpListener(localAddr, port);
server.Start();
while (true)
{
Console.Write("Waiting for a connection...-- ");
TcpClient client = server.AcceptTcpClient();
Console.WriteLine("new client connected");
try
{
ThreadPool.QueueUserWorkItem(new WaitCallback(HandleClient), client);
}
catch (Exception ex)
{ }
}
}
static void HandleClient(object tcpClient)
{
TcpClient client = (TcpClient)tcpClient;
Byte[] bytes = new Byte[135];
String data = null;
int i;
try
{
using (NetworkStream stream = client.GetStream())
using (StreamReader reader = new StreamReader(stream))
{
string inputLine = reader.ReadLineSingleBreak();
inputLine = inputLine + "#";
Console.WriteLine(inputLine);
URLObject oU = new URLObject();
oU = oDecode.TextFrameDecode(inputLine);
}
}
catch (Exception ex)
{ }
}
}
public static class StreamReaderExtensions
{
public static string ReadLineSingleBreak(this StreamReader self)
{
StringBuilder currentLine = new StringBuilder();
int i;
char c;
while ((i = self.Read()) >= 0)
{
c = (char)i;
if (c == '#')
{
break;
}
currentLine.Append(c);
}
return currentLine.ToString();
}
}
I need a mix of both... get all the data but then parse it correctly.
I did fix it by Pieter Witvoet advice:
static private TcpListener server = null;
static private Decode oDecode = new Decode();
static private string sLeftOver = string.Empty;
static void Main(string[] args)
{
Int32 port = 31001;
IPAddress localAddr = IPAddress.Parse("192.168.0.78"); //Local
server = new TcpListener(localAddr, port);
server.Start();
while (true)
{
Console.Write("Waiting for a connection...-- ");
TcpClient client = server.AcceptTcpClient();
Console.WriteLine("new client connected");
try
{
ThreadPool.QueueUserWorkItem(new WaitCallback(HandleClient), client);
}
catch (Exception ex)
{ }
}
}
static void HandleClient(object tcpClient)
{
TcpClient client = (TcpClient)tcpClient;
Byte[] bytes = new Byte[256];
String data = null;
int i;
try
{
NetworkStream stream = client.GetStream();
while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
{
data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
URLObject oU = new URLObject();
Console.WriteLine(data);
Console.WriteLine("");
//Split data here
string[] aData = Regex.Split(data, #"(?<=[#])");
foreach (string s in aData)
{
string sData = s;
sData = sLeftOver + sData;
if (sData.EndsWith("#"))
{
sLeftOver = string.Empty;
Console.WriteLine(sData);
Console.WriteLine("");
oU = oDecode.TextFrameDecode(sData);
}
else
{
sLeftOver = s;
}
}
}
}
catch (Exception ex)
{ }
}

Async TCPClient missing replies from server

I'm trying to implement an async TCP client that sends messages from a queue and listens to the response.
some of the server replies are lost (for example send 7 messages and get only 4 replies) and I don't understand why.
This is not a server issue, since the synchronize version I tested works just fine.
ConcurrentQueue<byte[]> msgQueue = new ConcurrentQueue<byte[]>();
public void Connect()
{
try
{
tcpclnt = new TcpClient();
Console.WriteLine("Connecting.....");
Task.Factory.StartNew(() =>
{
IAsyncResult res = tcpclnt.BeginConnect(_ip, _port, null, null);
if (!res.AsyncWaitHandle.WaitOne(CONNECTION_TIMEOUT_SEC * 1000))
{
tcpclnt.Close();
throw new ApplicationException("timed out trying to connect");
}
tcpclnt.EndConnect(res);
Receive();
byte[] message = null;
while (true)
{
message = null;
msgQueue.TryDequeue(out message);
if (message != null)
{
Stream stm = tcpclnt.GetStream();
Console.WriteLine("Transmitting..... " + Thread.CurrentThread.ManagedThreadId);//for debug
stm.Write(message.ToArray(), 0, message.ToArray().Length);
Receive();
}
}
});
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
//will be called from outside
public void SendMessage(byte[] msg)
{
Console.WriteLine("SendMessage..... " + Thread.CurrentThread.ManagedThreadId);//for debug
msgQueue.Enqueue(msg);
}
private void Receive()
{
SocketError error;
byte[] buffer = new byte[MAX_BUFFER_SIZE];
tcpclnt.Client.BeginReceive(buffer, 0, MAX_BUFFER_SIZE, SocketFlags.None, out error, new AsyncCallback(ReceiveHandler), buffer);
}
private void ReceiveHandler(IAsyncResult ar)
{
System.Console.WriteLine("ReceiveHandler " + Thread.CurrentThread.ManagedThreadId); //for debug
//End current async receive
int bytesRead = tcpclnt.Client.EndReceive(ar);
byte[] resultBuffer = (byte[]) ar.AsyncState;
// do a lot of things with resultBuffer
}

How to read and send data to client from server?

I'm trying to make a server client using a local console server on my pc and a client on windows phone 8.1. The problem that I have is that I don't know how to read the incoming data from the client. I've searched the internet and read serveral microsoft tutorials but they do not explain how to read the incoming data in the server. Here's what I have.
Client on windows phone 8.1:
private async void tryConnect()
{
if (connected)
{
StatusLabel.Text = "Already connected";
return;
}
try
{
// serverHostnameString = "127.0.0.1"
// serverPort = "1330"
StatusLabel.Text = "Trying to connect ...";
serverHost = new HostName(serverHostnameString);
// Try to connect to the
await clientSocket.ConnectAsync(serverHost, serverPort);
connected = true;
StatusLabel.Text = "Connection established" + Environment.NewLine;
}
catch (Exception exception)
{
// If this is an unknown status,
// it means that the error is fatal and retry will likely fail.
if (SocketError.GetStatus(exception.HResult) == SocketErrorStatus.Unknown)
{
throw;
}
StatusLabel.Text = "Connect failed with error: " + exception.Message;
// Could retry the connection, but for this simple example
// just close the socket.
closing = true;
// the Close method is mapped to the C# Dispose
clientSocket.Dispose();
clientSocket = null;
}
}
private async void sendData(string data)
{
if (!connected)
{
StatusLabel.Text = "Must be connected to send!";
return;
}
UInt32 len = 0; // Gets the UTF-8 string length.
try
{
StatusLabel.Text = "Trying to send data ...";
// add a newline to the text to send
string sendData = "jo";
DataWriter writer = new DataWriter(clientSocket.OutputStream);
len = writer.MeasureString(sendData); // Gets the UTF-8 string length.
// Call StoreAsync method to store the data to a backing stream
await writer.StoreAsync();
StatusLabel.Text = "Data was sent" + Environment.NewLine;
// detach the stream and close it
writer.DetachStream();
writer.Dispose();
}
catch (Exception exception)
{
// If this is an unknown status,
// it means that the error is fatal and retry will likely fail.
if (SocketError.GetStatus(exception.HResult) == SocketErrorStatus.Unknown)
{
throw;
}
StatusLabel.Text = "Send data or receive failed with error: " + exception.Message;
// Could retry the connection, but for this simple example
// just close the socket.
closing = true;
clientSocket.Dispose();
clientSocket = null;
connected = false;
}
}
(from http://msdn.microsoft.com/en-us/library/windows/apps/xaml/jj150599.aspx)
And the server:
public class Server
{
private TcpClient incomingClient;
public Server()
{
TcpListener listener = new TcpListener(IPAddress.Parse("127.0.0.1"), 1330);
listener.Start();
Console.WriteLine("Waiting for connection...");
while (true)
{
//AcceptTcpClient waits for a connection from the client
incomingClient = listener.AcceptTcpClient();
//start a new thread to handle this connection so we can go back to waiting for another client
Thread thread = new Thread(HandleClientThread);
thread.IsBackground = true;
thread.Start(incomingClient);
}
}
private void HandleClientThread(object obj)
{
TcpClient client = obj as TcpClient;
Console.WriteLine("Connection found!");
while (true)
{
//how to read and send data back?
}
}
}
It comes to the point where the server prints 'Connection found!', but I don't know how to go further.
Any help is appreciated!
EDIT:
Now my handleclientthread method looks like this:
private void HandleClientThread(object obj)
{
TcpClient client = obj as TcpClient;
netStream = client.GetStream();
byte[] rcvBuffer = new byte[500]; // Receive buffer
int bytesRcvd; // Received byte count
int totalBytesEchoed = 0;
Console.WriteLine("Connection found!");
while (true)
{
while ((bytesRcvd = netStream.Read(rcvBuffer, 0, rcvBuffer.Length)) > 0)
{
netStream.Write(rcvBuffer, 0, bytesRcvd);
totalBytesEchoed += bytesRcvd;
}
Console.WriteLine(totalBytesEchoed);
}
}
But it still doesn't write the bytes to the console
So... after a lot of searching the internet I have found a solution...
Server: to read from the server and send data back to the phone:
// method in a new thread, for each connection
private void HandleClientThread(object obj)
{
TcpClient client = obj as TcpClient;
netStream = client.GetStream();
Console.WriteLine("Connection found!");
while (true)
{
// read data
byte[] buffer = new byte[1024];
int totalRead = 0;
do
{
int read = client.GetStream().Read(buffer, totalRead, buffer.Length - totalRead);
totalRead += read;
} while (client.GetStream().DataAvailable);
string received = Encoding.ASCII.GetString(buffer, 0, totalRead);
Console.WriteLine("\nResponse from client: {0}", received);
// do some actions
byte[] bytes = Encoding.ASCII.GetBytes(received);
// send data back
client.GetStream().WriteAsync(bytes, 0, bytes.Length);
}
}
Phone(client): to send messages from the phone and read the messages from server:
private async void sendData(string dataToSend)
// import for AsBuffer(): using System.Runtime.InteropServices.WindowsRuntime;
{
if (!connected)
{
StatusLabel.Text = "Status: Must be connected to send!";
return;
}
try
{
byte[] data = GetBytes(dataToSend);
IBuffer buffer = data.AsBuffer();
StatusLabel.Text = "Status: Trying to send data ...";
await clientSocket.OutputStream.WriteAsync(buffer);
StatusLabel.Text = "Status: Data was sent" + Environment.NewLine;
}
catch (Exception exception)
{
if (SocketError.GetStatus(exception.HResult) == SocketErrorStatus.Unknown)
{
throw;
}
StatusLabel.Text = "Status: Send data or receive failed with error: " + exception.Message;
closing = true;
clientSocket.Dispose();
clientSocket = null;
connected = false;
}
readData();
}
private async void readData()
{
StatusLabel.Text = "Trying to receive data ...";
try
{
IBuffer buffer = new byte[1024].AsBuffer();
await clientSocket.InputStream.ReadAsync(buffer, buffer.Capacity, InputStreamOptions.Partial);
byte[] result = buffer.ToArray();
StatusLabel.Text = GetString(result);
}
catch (Exception exception)
{
if (SocketError.GetStatus(exception.HResult) == SocketErrorStatus.Unknown)
{
throw;
}
StatusLabel.Text = "Receive failed with error: " + exception.Message;
closing = true;
clientSocket.Dispose();
clientSocket = null;
connected = false;
}
}
The 'await clientSocket.InputStream.ReadAsync(buffer, buffer.Capacity, InputStreamOptions.Partial)' command in the readData method was very unclear for me. I didn't know you had to make a new buffer, and the ReadAsync-method fills it(as i inderstand it). Found it here: StreamSocket.InputStreamOptions.ReadAsync hangs when using Wait()

Categories

Resources