Windows Service closed when I disconnect one client socket - c#

I have a server listened on a socket. This server is a Windows Service.
My problem is: When I disconnect a client socket.Disconnect(false); the service so closed and other clients are closed forcibly or new connections refused. I think that when service kill this client thread, the service not back to main thread.
Paste my code used for service (server functionality). Is correct the management of threads?
I run server with
this.tcpListener = new TcpListener(ipEnd);
this.listenThread = new Thread(new ThreadStart(ListenForClients));
this.listenThread.Start();
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
Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm));
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
ASCIIEncoding encoder = new ASCIIEncoding();
System.Diagnostics.Debug.WriteLine(encoder.GetString(message, 0, bytesRead));
}
tcpClient.Close();
}
Sorry for my bad english and thanks for any suggestion

The code you provided seems to be almost correct.
The only reason your app will crash is the line
NetworkStream clientStream = tcpClient.GetStream();
If you look at the documentation for GetStream(), you could see that it can throw InvalidOperationException if client is not connected. So in the situation when client connects and immediately disconnects it could be an issue.
So just guard this code with try-catch.
Also sometimes you might not get an explicit exception report, but have crash in multithreaded applications. To handle such exceptions subscribe to the AppDomain.CurrentDomain.UnhandledException event.

Related

TCP/IP Continuously receive message without closing the connection

I've been watching the following pair of videos on how to create a TCP/IP connection : Server and Client
What I need to do is create a game (flipcard) in which I send only 2 coordinates for a matrix. Nothing more. Or less.
(the code will follow)
From what I've observed, he closes and reopens the connection, everytime he send a message. It's working. But what do I modify in the code to keep the connection open and detect when a message arrived ?
All my google-searches brought me to these 2 methods:
I have had luck using the socket object directly (rather than the TCP client). (But I do not want to use sockets)
Also uses sockets
When I click to start the server
private void bStartServer_Click(object sender, EventArgs e)
{
Thread tcpServerRunThread = new Thread(new ThreadStart(TCPServerRun));
tcpServerRunThread.Start();
}
Server Runs and waits for a connection
private void TCPServerRun()
{
TcpListener tcpListener = new TcpListener(IPAddress.Any, 2016);
tcpListener.Start();
updateUI("Listening");
while (true)
{
TcpClient client = tcpListener.AcceptTcpClient();
updateUI("Connected");
Thread tcpHandlerThread = new Thread(new ParameterizedThreadStart(tcpHandler));
tcpHandlerThread.Start(client);
}
}
I handle my message
private void tcpHandler(object client)
{
TcpListener tcpListener = new TcpListener(IPAddress.Any, 5004);
TcpClient mClient = (TcpClient)client;
NetworkStream stream = mClient.GetStream();
byte[] message = new byte[1024];
stream.Read(message,0, message.Length);
updateUI("New message = " + Encoding.ASCII.GetString(message));
stream.Close();
mClient.Close();
}
NOTE: updateUI is a function made by him to update a listbox item
Client side - almost like the server side
`private void button1_Click(object sender, EventArgs e)
{
Thread mThread = new Thread(new ThreadStart(ConnectAsClient));
mThread.Start();
}
private void ConnectAsClient()
{
// aici putem inlocui cu adresa de IP dorita
//client.Connect(IPAddress.Parse(textBox.Text), 5004);
client = new TcpClient();
//client.Connect(IPAddress.Parse("127.0.0.1"), 2016); // for when I'm not connected to network
client.Connect(IPAddress.Parse("my_ip_here"), 2016); // for when I am connected to the network
updateUI("connected");
NetworkStream stream = client.GetStream();
string s = "Hello world!";
byte[] message = Encoding.ASCII.GetBytes(s);
stream.Write(message, 0, message.Length);
this.updateUI("Message sent!");
stream.Close();
// client.Close();
}`
If I'm not wrong, everytime he connects again, he creates a new connection, and not open the old one, right?
(It's my first time using TCP/IP, learning on my own, so I'd rather not use sockets, if possible)
-----------------------------------------------------------------------
Full link to my code (slighty modified from the videos provided at the beginning):
TCPClient
TCPServer
You are reconnecting every time you send the message. Use two different methods for this; one for connecting to the server and then another one for actually sending the message. Like so:
TcpClient client;
private void ConnectAsClient()
{
//client.Connect(IPAddress.Parse(textBox.Text), 5004);
client = new TcpClient();
//client.Connect(IPAddress.Parse("127.0.0.1"), 2016);
client.Connect(IPAddress.Parse("my_ip_here"), 2016);
updateUI("connected");
}
void SendMessage()
{
NetworkStream stream = client.GetStream();
string s = "Hello world!";
byte[] message = Encoding.ASCII.GetBytes(s);
stream.Write(message, 0, message.Length);
this.updateUI("Message sent!");
}

Connection Refused with TCP socket Error # 10061

I'm creating a small chat (1-1) application to learn network programming and when creating the socket using TCP protocol, the Socket.Connect() always return error 10061.
However, if I make the socket UDP, I don't see the issue.
Here is my code:
myEndPoint = new IPEndPoint(IPAddress.Parse(_txtMyIPAdress.Text), int.Parse(_txtMyPort.Text));
TargetSideEndPoint = new IPEndPoint(IPAddress.Parse(_txtTargetIPAddress.Text), int.Parse(_txtTargetPort.Text));
mySocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
mySocket.Bind(myEndPoint);
mySocket.Connect(TargetSideEndPoint);
byte[] receivedBuffer = new byte[MAX_BUFFER_SIZE = 1024];
ReceivePackets(mySocket, receivedBuffer);//My function
Can any one help me?
Update:
I'm not using Listen() the issue is when I call Connect()
I already tried multiple ports with the same issue and I'm currently testing on 1 PC by opening 2 instances from my application and using 2 different ports while firewall is off.
Thanks,
For TCP, which is a connection oriented protocol, you would need a server and a client.
The server must listen for incoming connections and the client should initiate the connection. Then, the client will be able to communicate with the server and exchange data.
Here is a simple working example:
void Main()
{
Console.WriteLine("Starting listener thread");
Thread serverThread = new Thread(ListenerThreadProc);
serverThread.Start();
Console.WriteLine("Waiting 500 milliseconds to allow listener to start");
Thread.Sleep(500);
Console.WriteLine("Client: Connecting to server");
TcpClient client = new TcpClient();
client.Connect(IPAddress.Loopback, 12345);
Console.WriteLine("Client: Connected to server");
byte[] buffer = new byte[5];
Console.WriteLine("Client: Receiving data");
using (NetworkStream clientStream = client.GetStream())
clientStream.Read(buffer, 0, buffer.Length);
Console.WriteLine("Client: Received data: " + buffer.Aggregate("", (s, b) => s += " " + b.ToString()));
}
void ListenerThreadProc()
{
TcpListener listener = new TcpListener(IPAddress.Any, 12345);
listener.Start();
Console.WriteLine("Server: Listener started");
Console.WriteLine("Server: Waiting for client to connect");
TcpClient client = listener.AcceptTcpClient();
Console.WriteLine("Server: Client connected");
listener.Stop();
Console.WriteLine("Server: Listener stopped");
Console.WriteLine("Server: Sending data");
byte[] buffer = new byte[] { 1, 2, 3, 4, 5 };
using (NetworkStream clientStream = client.GetStream())
clientStream.Write(buffer, 0, buffer.Length);
Console.WriteLine("Server: Sent data");
}
In this example, made as simple as it gets, you have a server accepting a single client to which it sends some data. The client connects, reads the data and then displays it.
A real-life server would spin new threads (or tasks, for async model) to serve the client's request as soon as the client would connect and carry on listening for new connections.

How to test TcpListener for localhost and port number in c#

I have a code in c# which reads the data from tcp ipaddress and port number but my problem is this that i dont have any testing plateform with ipaddress and port number to test the application.My concern is this that is there any way by which i can test my code in local environmnet..
Here is my code..
public class Listener
{
private TcpListener tcpListener;
private Thread listenThread;
// Set the TcpListener on port 8081.
Int32 port = 8081;
IPAddress localAddr = IPAddress.Parse("192.168.1.3");
Byte[] bytes = new Byte[256];
public 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
Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm));
clientThread.Start(client);
}
}
public 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
// System.Windows.MessageBox.Show("socket");
break;
}
if (bytesRead == 0)
{
//the client has disconnected from the server
// System.Windows.MessageBox.Show("disc");
break;
}
//message has successfully been received
ASCIIEncoding encoder = new ASCIIEncoding();
String textdata = encoder.GetString(message, 0, bytesRead);
System.IO.File.AppendAllText(#"D:\ipdata.txt", textdata);
}
tcpClient.Close();
}
}
Please help me to solve this ..
Thanks in advance..
To test the TCP listening application, you obviously need to write TCP transferring one. You can write it and:
Run them simultaneously
OR
Run listener on your OS and transmitter in virtual machine. I made so and has written a post on my blog on Russian (sources are also available for download).
I think you can configure the listener to 127.0.0.1 and test logic via localhost connetcion if you have transmitting part of system
Use RESTClient chrome/firefox AddOn (http://restclient.net/) to send data to IP and Port in Intranet environment, I use this

C# TCP Client having trouble listening to Server and updating GUI

I have a GUI with 2 buttons and a text box. Button1 starts a server and has it listen for clients. Button 2 sends a connection request to the server and starts to listen for anything the server will send to the client (responses). Although w/ my current code when the Server sends the reply and I try to write it to a text box the whole system hangs.
Code as seen below:
Server Class:
class Server
{
private TcpListener tcpListener;
private Thread listenThread;
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
Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm));
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
ASCIIEncoding encoder = new ASCIIEncoding();
byte[] buffer = encoder.GetBytes("Hello Client!");
clientStream.Write(buffer, 0, buffer.Length);
clientStream.Flush();
}
tcpClient.Close();
}
public Server()
{
this.tcpListener = new TcpListener(IPAddress.Any, 3000);
this.listenThread = new Thread(new ThreadStart(ListenForClients));
this.listenThread.Start();
}
}
GUI class:
private void buttonServerStart_Click(object sender, EventArgs e)
{
Server Myserver = new Server();
}
//Greet the Server and listen for response...
private void EthStartB_Click(object sender, EventArgs e)
{
TcpClient client = new TcpClient();
byte[] message = new byte[4096];
int bytesRead;
IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 3000);
client.Connect(serverEndPoint);
NetworkStream clientStream = client.GetStream();
ASCIIEncoding encoder = new ASCIIEncoding();
byte[] buffer = encoder.GetBytes("Hello Server!");
clientStream.Write(buffer, 0, buffer.Length);
clientStream.Flush();
//start listening
this.ClientListener.Start();
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
tb_recieved.Clear();
tb_recieved.Text=encoder.GetString(message,0,bytesRead);
}
}
TcpListener ClientListener = new TcpListener(IPAddress.Parse("127.0.0.1"), 3000);
private void EthEndB_Click(object sender, EventArgs e)
{
Form3 frmT = new Form3();
frmT.Show();
}
}
The issue is when private void EthStartB_Click(object sender, EventArgs e) calls the code line of tb_recieved.Text=encoder.GetString(message,0,bytesRead);
The program hangs because you have a while(true) loop in EthStartB_Click which runs on UI thread. clientStream.Read call will block UI thread.
Move the receive logic on a new thread and set the textbox content using Control.Invoke or Dipatcher.Invoke depending on whether you are on WinForms or WPF - and do that only if you do have some content in the message to be written to textbox.
There also another issue, since you have the tcpClient.Close() outside the while loop on the server, neither client nor server will disconnect. Both will block on their respective stream.Read calls.
Since you are running both client and server on same machine, that TcpListener ClientListener is not required and will not play well with the server already listening on the same port.

Concurrent connections in C# socket

There are three apps run at the same time, 2 clients and 1 server. The whole system should function as following:
The client sends an serialized object to server then server receives that object as a stream, finally the another client get that stream from server and deserialize it.
This is the sender:
TcpClient tcpClient = new TcpClient();
tcpClient.Connect("127.0.0.1", 8888);
Stream stream = tcpClient.GetStream();
BinaryFormatter binaryFormatter = new BinaryFormatter();
binaryFormatter.Serialize(stream, event); // Event is the sending object
tcpClient.Close();
Server code:
TcpListener listener = new TcpListener(IPAddress.Parse("127.0.0.1"), 8888);
listener.Start();
Console.WriteLine("Server is running at localhost port 8888 ");
while (true)
{
Socket socket = listener.AcceptSocket();
try
{
Stream stream = new NetworkStream(socket);
// Typically there should be something to write the stream
// But I don't knwo exactly what should the stream write
}
catch (Exception e)
{
Console.WriteLine("Exception: " + e.Message);
Console.WriteLine("Disconnected: {0}", socket.RemoteEndPoint);
}
}
The receiver:
TcpClient client = new TcpClient();
// Connect the client to the localhost with port 8888
client.Connect("127.0.0.1", 8888);
Stream stream = client.GetStream();
Console.WriteLine(stream);
when I run only the sender and server, and check the server, server receives correctly the data. The problem is when I run the receiver, everything is just disconnected. So where is my problem ? Could anyone point me out ? Thanks

Categories