I have the following configuration for the server, that connects successfully to the client and runs the following threads.
My issue is when the client disconnects, it doesn't catch the exception:
private void Form1_Load(object sender, EventArgs e)
{
th_StartListen = new Thread(new ThreadStart(StartListen));
th_StartListen.Start();
txtCmdOutput.Focus();
}
private void StartListen()
{
//Creating a TCP Connection and listening to the port
tcpListener = new TcpListener(System.Net.IPAddress.Any, 6666);
tcpListener.Start();
toolStripStatusLabel1.Text = "Listening on port 6666 ...";
int counter = 0;
appStatus = 0;
while (true)
{
try
{
client = tcpListener.AcceptTcpClient();
counter++;
clientList.Add(client);
var ipend = (IPEndPoint)client.Client.RemoteEndPoint;
//Updating status of connection
toolStripStatusLabel1.Text = "Connected from " + ipend.Address.ToString();
appStatus = 1;
th_inPutStream = new Thread(() => outPutStream(client));
th_inPutStream.Start();
th_inPutStream = new Thread(() => inPutStream(client));
th_inPutStream.Start();
}
catch (Exception err)
{
Cleanup();
}
}
}
It simply loops back and stops at client = tcpListener.AcceptTcpClient(); .
Would appreciate some ideas behind this.
Thanks!
Look carefully at your logic. Since both input stream and output stream are running on separate threads, the code will continue executing after starting the second thread, and when it does so, it will loop around, hit the true condition, and then start listening for a new client connection immediately.
Your exception isn't being caught because you're not generating an exception. A client closing it's connection to the server isn't necessarily an exception generating event.
Related
I have this code on my server side.
public static void Data_IN(object cSocket)
{
Socket clientSocket = (Socket)cSocket;
byte[] Buffer;
int readBytes;
while (true)
{
Buffer = new byte[clientSocket.SendBufferSize];
readBytes = clientSocket.Receive(Buffer);
if (readBytes > 0)
{
Packet p = new Packet(Buffer);
DataManager(p);
}
}
}
And the main problem is that when I stop debugging the code the server always crashes and says
System.Net.Sockets.SocketException: the remote server closed connection
The error is always at readBytes = clientSocket.Recieve(Buffer);
That is the only way I can crash the server, my only concern is when someone uses the chat program that I have created and his/hers computer crashes the chat server will go down and I always need to restart the server.
Clientside code below which executes when closing the window
private void MainWindow_Closed(object sender, EventArgs e)
{
if (isConnected)
{
Packet p = new Packet(PacketType.CloseConnection, ID);
p.data.Add(login);
p.data.Add("exits from chat");
socket.Send(p.ToBytes());
socket.Close();
isConnected = false;
thread.Abort();
}
}
On below there is the code part which uses data_in, that code is on the client side
private void ConnectBtn_Click(object sender, RoutedEventArgs e)
{
if (string.IsNullOrWhiteSpace(Login.Text))
{
MessageBox.Show("Add username");
}
else if (!IPAddress.TryParse(serverIP.Text, out ipAdress))
{
MessageBox.Show("Add valid ip");
}
else
{
ClearRequireMsg();
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint ipEndPoint = new IPEndPoint(ipAdress, 4242);
try
{
socket.Connect(ipEndPoint);
login = Login.Text;
isConnected = true;
ConnectBtn.IsEnabled = false;
SendBtn.IsEnabled = true;
thread = new Thread(Data_IN);
thread.Start();
}
catch (SocketException ex)
{
AddMsgToBoard("Error during connecting to server", "System");
}
}
}
You're calling the function Data_IN without passing any parameter.
thread = new Thread(Data_IN);
Right way:
new Thread(() => Data_IN(socket));
Im implementing a WebService with TCP. The webservice is the Server side that accept multiple clients. Is there any suggestions on how to configure a default port where to start the tcp clients? And with every client connected (aprox. 10 clients) will have an assigned port.
(I'm using Visual Studio 2010 the language is c#, Here is a code block for accepting the clients.)
Any suggestions will be accepted. Thanks!
private void StartListening(object sender, EventArgs e)
{
try
{
//Will move one the array of threads
index++;
//Will get the current IP Address
IPAddress ipaddr = IPAddress.Any;
//Port where the data will pass.
//First Port in use. 10,000
int Port = 10000;
if (true)
{
_TCPListener = new TcpListener(ipaddr, Port);
Port = Port + 1;
//Start Listening
_TCPListener.Start();
ThreadStart.Add(new ThreadStart(() => _TCPListener.BeginAcceptTcpClient(CompleteAcceptClient, _TCPListener)));
Thread.Add(new Thread(ThreadStart[index]));
Thread[index].Start();
}
else
{
_TCPListener = new TcpListener(ipaddr, Port + 2);
_TCPListener.Start();
ThreadStart delegateT = new ThreadStart(() => _TCPListener.BeginAcceptTcpClient(CompleteAcceptClient, _TCPListener));
Thread T = new Thread(delegateT);
T.Start();
}
}
catch(Exception ex)
{
throw ex;
}
}
//Here is the accept client method.
private void CompleteAcceptClient(IAsyncResult iar)
{
TcpListener tcpl = (TcpListener)iar.AsyncState;
try
{
ThreadStart delegateR = new ThreadStart(() => _TCPClient = tcpl.EndAcceptTcpClient(iar));
Thread R = new Thread(delegateR);
R.Start();
mRx = new byte[1024];
_TCPClient.GetStream().BeginRead(mRx, 0, mRx.Length, onCompleteReadFromTCPClientStream, _TCPClient);
}
catch(Exception e)
{
throw e;
}
}
I need a way to separate GUI thread when i try to connect sockets
My C# code connects properly without any hang in GUI when the lan cable to connected to the port of PC when my APP is running. no issue there.
But when there is no Lan port connected to the PC where my APP is trying to connect, Ideal behavior i am expecting is that the APP waits for a Socket connection and the GUI doesn't freeze.
I tried using threads like TaskFactory.StartNew Method (Action)
But i see that it successfully resolves GUI hang but doesn't connect to the lan sometimes
below code is my latest attempt to solve this issue but found it no good.
try
{
Thread.Sleep(100);
TcpListener serverSocket = new TcpListener(IPAddress.Any,ports);
clientSocket = default(TcpClient);
int counter = 0;
serverSocket.Start();
counter += 1;
dispatcher.Invoke(new Action(() =>
{
clientSocket = serverSocket.AcceptTcpClient();
}));
MessageBox.Show(ports + " " + "Connected!");
}
catch (Exception w)
{
MessageBox.Show(ports + " " + "Connection error!");
}
Help needed: When No lan port is connected to the PC, and when the APP tries to connect to that port, instead of GUI hang it must wait gracefully.
You should use the Async or Begin method (depending if your environment supports async/await or not).
Due to the fact that you only have VS2010 you should use the Begin approach:
private void InitializeListiner()
{
var listener = new TcpListener(IPAddress.Any, ports);
listener.Start();
listener.BeginAcceptTcpClient(OnClientConnected, listener);
}
private void OnClientConnected(IAsyncResult asyncResult)
{
var listener = (TcpListener)asyncResult.AsyncState;
var client = listener.EndAcceptTcpClient(asyncResult);
listener.BeginAcceptTcpClient(OnClientConnected, listener);
// ToDo: send and receive data from/to client...
}
Try this:
var ports = 1234;
try
{
Thread.Sleep(100);
var serverSocket = new TcpListener(IPAddress.Any, ports);
var clientSocket = default(TcpClient);
int counter = 0;
serverSocket.Start();
counter += 1;
var source = new CancellationTokenSource();
Task.Factory.StartNew(() =>
{
while(true)
{
clientSocket = serverSocket.AcceptTcpClient();
MessageBox.Show(ports + " " + "Connected!");
}
}, source.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default);
}
catch (Exception w)
{
MessageBox.Show(ports + " " + "Connection error!");
}
This is a follow on from this question
After some more Googling last night I managed to find a nice TCP tutorial I could follow that would allow me to look for connections on an Ip address and port number and display the data that is being sent.
However, I have an issue where my client connects once, I send a message and display it in the debug log but when I stop the application and run it again, Unity freezes. I'm at a loss as to why this happening. Could someone please take a look over this code to see where it might be happening and what I can do to fix it?
I also seem to boot out the connection as soon as I receive a message as well, why is that? The server can re-connect, but I want it to keep the connection once it has it.
public class TCP : MonoBehaviour
{
string ip_address = "127.0.0.1";
int port = 22;
Thread listen_thread;
TcpListener tcp_listener;
Thread clientThread;
TcpClient tcp_client;
bool isTrue = true;
// Use this for initialization
void Start ()
{
IPAddress ip_addy = IPAddress.Parse(ip_address);
tcp_listener = new TcpListener(ip_addy, port);
listen_thread = new Thread(new ThreadStart(ListenForClients));
listen_thread.Start();
Debug.Log("start thread");
}
private void ListenForClients()
{
this.tcp_listener.Start();
while(isTrue == true)
{
//blocks until a client has connected to the server
TcpClient client = this.tcp_listener.AcceptTcpClient();
//create a thread to handle communication
//with connected client
clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm));
clientThread.Start(client);
Debug.Log("Got client " + client);
}
}
private void HandleClientComm(object client)
{
tcp_client = (TcpClient)client;
NetworkStream client_stream = tcp_client.GetStream();
byte[] message = new byte[4096];
int bytes_read;
while(isTrue == true)
{
bytes_read = 0;
try
{
//blocks until a client sends a message
bytes_read = client_stream.Read(message, 0, 4096);
//Debug.Log(message);
}
catch (Exception e)
{
//a socket error has occured
Debug.Log(e.Message);
break;
}
if(bytes_read == 0)
{
//client has disconnected
Debug.Log("Disconnected");
tcp_client.Close();
break;
}
ASCIIEncoding encoder = new ASCIIEncoding();
Debug.Log(encoder.GetString(message,0,bytes_read));
}
if(isTrue == false)
{
tcp_client.Close();
Debug.Log("closing tcp client");
}
}
void OnApplicationQuit()
{
try
{
tcp_client.Close();
isTrue = false;
}
catch(Exception e)
{
Debug.Log(e.Message);
}
}
}
Here is a screen shot of my debug log as well to show whats happening:
update
updated code that has fixed the kicking of clients. The freeze issue is still persistent when I stop the unity application and re-start it.
further update
So after a little further experimenting I have worked out that my project isn't actually freezing. When I start the server (Unity) app the first time everything works fine. But when I close it and try to re run the server, it freezes, until I connect to it with a client. At which point the server works as normal.
So I think I'm not closing the open socket when I close down the server. How can I do that?
You must close the TCP socket that is listening. If you start the application for the first time, the TCP socket will be open. When you stop the application, the TCP socket is still opened and runs in the background.
void OnApplicationQuit()
{
try
{
tcp_client.Close();
isTrue = false;
}
catch(Exception e)
{
Debug.Log(e.Message);
}
// You must close the tcp listener
try
{
tcp_listener.Stop();
isTrue = false;
}
catch(Exception e)
{
Debug.Log(e.Message);
}
}
Im am trying to make an Windows Form App. The app uses multithreading and each thread calls a methos and it updates controls created on the main thread. I use invoke to update the controls and the app works on Windows server enterprise but it doesent on Windows 7 64 bit. On WIndows 7 the application stops doing anything after updating the interface 2 times. I don't know what seems to be the problem. I tried with multiple threads and with task(Task.Factory.StartNew()) and i had the same result(updates the control 2 times). No error message.
Thank you.
EDIT:
In CallMethod() i'm calling a WCF and waiting for respont. It seems that WCF call is returning something for the first two threads and for the rest it's not...
code:
Main method:
for (int i = 0; i < NoThreads; i++)
{
int index = i;
Thread t = new Thread(CallMethod);
t.Name = "Thread [" + Cicle + "] Cicle [" + i + "]";
threads[i] = t;
}
for (int i = 0; i < NoThreads; i++)
{
threads[i].Start();
}
CallMethod:
private string CallMethod()
{
try
{
//calling a webservice
string message = .....
if (txtResult.InvokeRequired)
{ txtResult.Invoke((MethodInvoker)(() => txtResult.AppendText(message))); }
catch
{throw;}
}
For debugging, make sure all paths through CallMethod() update the UI (even if it's just with a "got to this point" text). It seems like txtResult.InvokeRequired may be false, or perhaps you are getting an exception from the web request.
Problem Solved
I had to close the connection after calling the WCF in each thread
A sample of working on x64 machine (Windows 7) for thread:
class Server
{
private TcpListener tcpListener;
private Thread listenThread;
private static string rootPath = "";
public Server()
{
IPAddress ipAddress = Dns.Resolve("localhost").AddressList[0];
this.tcpListener = new TcpListener(ipAddress, 9501);
//this.tcpListener = new TcpListener(RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["Endpoint1"].IPEndpoint);
this.listenThread = new Thread(new ThreadStart(ListenForClients));
Trace.WriteLine("Server Working", "Information");
this.listenThread.Start();
}
private void ListenForClients()
{
this.tcpListener.Start();
Trace.WriteLine("Server TcpListener Started", "Information");
while (true)
{
//blocks until a client has connected to the server
TcpClient client = this.tcpListener.AcceptTcpClient();
Trace.WriteLine("Server TcpListener New Client", "Information");
// create a thread to handle the client
//ParameterizedThreadStart HandleClientConn;
Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm));
clientThread.Start(client);
}
}
private void HandleClientComm(object client)
{
Trace.WriteLine("Server TcpListener New Client Handle Thread", "Information");
TcpClient tcpClient = (TcpClient)client;
NetworkStream nStream = tcpClient.GetStream();
Image img = Image.FromStream(nStream);
Trace.WriteLine("Server TcpListener Image is received", "Information");
string imageName = client.GetHashCode() + ".jpg";
string imagePath = Path.Combine(Environment.GetEnvironmentVariable("RoleRoot") + #"\", #"approot\"+ imageName);
img.Save(imagePath, ImageFormat.Jpeg);
rootPath = Environment.GetEnvironmentVariable("RoleRoot");
Dictionary<string, string> templates = GetTemplates();
string sDataDir = String.Format("{0}StasmData\\", rootPath);
StasmHelper stasm = new StasmHelper();
Face retVal = stasm.GetHumanFace(imagePath, sDataDir, templates);
File.Delete(imagePath);
}