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);
}
Related
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.
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!");
}
so i've got a Visual Studio C# WindowsForms program. It has the ability to open up a socket in the background to let tcp clients join. they can then exchange data.
the problem is that writing data to that tcp socket is a problem for me. reading data is successfull.
so my form1:
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private TcpListener listener;
private Socket socket;
...
private void Form1_Load(object sender, EventArgs e)
{
comboBox1.SelectedIndex = 0;
webBrowser1.GoHome();
const int LIMIT = 1; //5 concurrent clients
listener = new TcpListener(IPAddress.Any, 8080);
listener.Start();
for (int i = 0; i < LIMIT; i++)
{
Thread t = new Thread(() => {
socket = EmployeeTCPServer.accepting(listener, this);
});
t.Start();
}
toolStripStatusLabel1.Text = "Waiting for Connection";
listBox1.Items.Add("Waiting");
}
...
private void button3_Click(object sender, EventArgs e)
{
StreamWriter sw = new StreamWriter(new NetworkStream(socket));
sw.WriteLine("-> Stuff");
}
The accepting of the client must be threaded in case the form continues working, which should be the source of all evil. And my TCP Server Class:
class EmployeeTCPServer
{
public static Socket accepting(TcpListener plistener, Form1 parent)
{
Socket soc = plistener.AcceptSocket();
parent.SetText("Connection accepted");
Stream s = new NetworkStream(soc);
StreamReader sr = new StreamReader(s);
StreamWriter swa = new StreamWriter(s);
swa.AutoFlush = true; // enable automatic flushing
swa.WriteLine("-> Connected to Iface");
Service(plistener, parent, soc);
return soc;
}
public static void Service(TcpListener plistener, Form1 parent, Socket psoc)
{
bool EMPFANG = true;
Stream s = new NetworkStream(psoc);
StreamReader sr = new StreamReader(s);
StreamWriter swa = new StreamWriter(s);
swa.AutoFlush = true;
while (EMPFANG)
{
string name = sr.ReadLine();
parent.LBSetText(name);
if(name=="exit")
{
swa.WriteLine("-> Exit OK");
EMPFANG = false;
}
}
psoc.Close();
}
}
The problem crashes when i click on "Antworten" (Button3). It says that sw is NULL, which for me means that the returning of the socket descriptor doesn't work.
I also tried to make a new method in the tcp server class (something like "send_msg_to_client(string pmessage)") but then i dont know how to call that method.
So which method is the right one and how can i send data on button click?
Thanks in advance for help!
It sounds like you want a simple "chat" system with specific messages send between the client and the host.
Try to have a look at this project:
http://www.eng.northampton.ac.uk/~espen/CSY2026/CSY2026CSharp5.htm
Maybe it can be to some inspiration.
Let me know if it helps!
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);
}
}
I am making a chat service for a game,
I am using a TCP listener an client for the account information, some sort of login service. I'm wondering if i can keep the socked the client connected to the server with, to check if he is still online, and keep sending him messages if he has new messages.
I already tried making a list of sockets for the login queue, but it disconnected the previous socket to to server as soon as i accepted a new socket.
byte[] usernameByte = new byte[100];
int usernameRecieved = s.Receive(usernameByte);
//guiController.setText(System.DateTime.Now + " Recieved Login...");
byte[] passByte = new byte[100];
int passRecieved = s.Receive(passByte);
//guiController.setText(System.DateTime.Now + " Recieved Password...");
string username = "";
string password = "";
for (int i = 0; i < usernameRecieved; i++)
username += (Convert.ToChar(usernameByte[i]));
for (int i = 0; i < passRecieved; i++)
password += (Convert.ToChar(passByte[i]));
if (DomainController.getInstance().checkAccount(username, password))
{
ASCIIEncoding asen = new ASCIIEncoding();
s.Send(asen.GetBytes("true"));
s.Send(asen.GetBytes("U are succesfully logged in, press enter to continue"));
guiController.setText(serverName,System.DateTime.Now+"");
guiController.setText(serverName, "Sent Acknowledgement - Logged in");
}
else
{
ASCIIEncoding asen = new ASCIIEncoding();
s.Send(asen.GetBytes("false"));
s.Send(asen.GetBytes("U are NOT logged in, press enter to continue"));
guiController.setText(serverName, System.DateTime.Now + "");
guiController.setText(serverName, "\nSent Acknowledgement - Not logged in");
}
This is the code i currently use to check the account information the user send me. Right after i send this the user dropd the connection and i move on to the next one.
I have tried making 1 list of seperate sockets and processing them one by one, but that failed because the previous socket's connection dropped, even tho it were 2 different machines that tried to connect.
Does anyone have a sollution / a way to save sockets, that I can use to make the program keep all the connections alive? so i can send a message from user 1 to user 2, and just use the socket they connected with? or do i need to add an id every time they make a connection?
EDIT
The client Code: (this is just a test client)
while (true)
{
TcpClient tcpclnt = new TcpClient();
Console.WriteLine("Connecting.....");
tcpclnt.Connect("xx.xxx.xxx.xx", 26862);
// use the ipaddress as in the server program
while(!(checkResponse(tcpclnt.GetStream())))
{
Thread.Sleep(1000);
}
Console.WriteLine("Connected");
Console.Write("Enter the string to be transmitted : ");
String str = Console.ReadLine();
if (str == "")
{
str = " ";
}
Stream stm = tcpclnt.GetStream();
ASCIIEncoding asen = new ASCIIEncoding();
byte[] ba = asen.GetBytes(str);
Console.WriteLine("Transmitting.....");
stm.Write(ba, 0, ba.Length);
Console.Write("Enter the string to be transmitted : ");
String str2 = Console.ReadLine();
if (str2 == "")
{
str2 = " ";
}
Stream stm2 = tcpclnt.GetStream();
ASCIIEncoding asen2 = new ASCIIEncoding();
byte[] ba2 = asen2.GetBytes(str2);
Console.WriteLine("Transmitting.....");
stm.Write(ba2, 0, ba2.Length);
if (str == "false")
{
blijvenWerken = false;
}
byte[] bb = new byte[100];
int k = stm.Read(bb, 0, 100);
for (int i = 0; i < k; i++)
Console.Write(Convert.ToChar(bb[i]));
byte[] bb2 = new byte[100];
int k2 = stm.Read(bb2, 0, 100);
Console.Write("\n");
for (int i = 0; i < k2; i++)
Console.Write(Convert.ToChar(bb2[i]));
Console.WriteLine("\n");
tcpclnt.Close();
Thread.Sleep(1000);
}
Server getting the sockets:
This bit of code is on the loginserver, its because i can only accept 1 socket every time to keep the connection alive, that i put queueCount on a maximum of 1.
I want to be able to make a list of Sockets that i accepted to add to a User account.
while (loginServerOn)
{
if (queueCount < 1)
{
if (loginServer.getLoginListener().Pending())
{
loginQueue.Add(loginServer.getSocket());
ASCIIEncoding asen = new ASCIIEncoding();
Socket s = loginQueue.First();
try
{
s.Send(asen.GetBytes("true"));
queueCount++;
}
catch
{
loginQueue.Remove(s);
}
}
}
}
The function that returns the accepted socket.
public Socket getSocket()
{
return myList.AcceptSocket();
}
EDIT: Essence of the question
I want to add the socked or client recieved to my Account object, so every connection has an Account its linked to, when i want to send a message to a certain account, it should send a message to the socked or client bound to that account, can you help/show me how i can achieve this?
This is still c# and sockets but my approach is different to yours.
I went with the concept of a "connectedCleint" which is similar in purpose to what you've called an account.
I have a class called ServerTerminal which is responsible for accepting and top level management of socket connections. In this i've got:
public Dictionary<long, ConnectedClient> DictConnectedClients =
new Dictionary<long, ConnectedClient>();
So this is my list of connected clients indexed by the sockethandle.
To accept connections i've got a routine:
public void StartListen(int port)
{
socketClosed = false;
IPEndPoint ipLocal = new IPEndPoint(IPAddress.Any, port);
listenSocket = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
//bind to local IP Address...
//if ip address is allready being used write to log
try
{
listenSocket.Bind(ipLocal);
}
catch (Exception excpt)
{
// Deal with this.. write your own log code here ?
socketClosed = true;
return;
}
//start listening...
listenSocket.Listen(100); // Max 100 connections for my app
// create the call back for any client connections...
listenSocket.BeginAccept(new AsyncCallback(OnClientConnection), null);
}
So when a client connects it then fires off:
private void OnClientConnection(IAsyncResult asyn)
{
if (socketClosed)
{
return;
}
try
{
Socket clientSocket = listenSocket.EndAccept(asyn);
ConnectedClient connectedClient = new ConnectedClient(clientSocket, this, _ServerTerminalReceiveMode);
//connectedClient.MessageReceived += OnMessageReceived;
connectedClient.Disconnected += OnDisconnection;
connectedClient.dbMessageReceived += OndbMessageReceived;
connectedClient.ccSocketFaulted += ccSocketFaulted;
connectedClient.StartListening();
long key = clientSocket.Handle.ToInt64();
if (DictConnectedClients.ContainsKey(connectedClient.SocketHandleInt64))
{
// Already here - use your own error reporting..
}
lock (DictConnectedClients)
{
DictConnectedClients[key] = connectedClient;
}
// create the call back for any client connections...
listenSocket.BeginAccept(new AsyncCallback(OnClientConnection), null);
}
catch (ObjectDisposedException excpt)
{
// Your own code here..
}
catch (Exception excpt)
{
// Your own code here...
}
}
The crucial part of this for you is:
// create the call back for any client connections...
listenSocket.BeginAccept(new AsyncCallback(OnClientConnection), null);
This sets up the serverterminal to receive new connections.
Edit:
Cut down version of my connectedclient:
public class ConnectedClient
{
private Socket mySocket;
private SocketIO mySocketIO;
private long _mySocketHandleInt64 = 0;
// These events are pass through; ConnectedClient offers them but really
// they are from SocketIO
public event TCPTerminal_ConnectDel Connected
{
add
{
mySocketIO.Connected += value;
}
remove
{
mySocketIO.Connected -= value;
}
}
public event TCPTerminal_DisconnectDel Disconnected
{
add
{
mySocketIO.Disconnected += value;
}
remove
{
mySocketIO.Disconnected -= value;
}
}
// Own Events
public event TCPTerminal_TxMessagePublished TxMessageReceived;
public delegate void SocketFaulted(ConnectedClient cc);
public event SocketFaulted ccSocketFaulted;
private void OnTxMessageReceived(Socket socket, TxMessage myTxMessage)
{
// process your message
}
private void OnMessageSent(int MessageNumber, int MessageType)
{
// successful send, do what you want..
}
public ConnectedClient(Socket clientSocket, ServerTerminal ParentST)
{
Init(clientSocket, ParentST, ReceiveMode.Handler);
}
public ConnectedClient(Socket clientSocket, ServerTerminal ParentST, ReceiveMode RecMode)
{
Init(clientSocket, ParentST, RecMode);
}
private void Init(Socket clientSocket, ServerTerminal ParentST, ReceiveMode RecMode)
{
ParentServerTerminal = ParentST;
_myReceiveMode = RecMode;
_FirstConnected = DateTime.Now;
mySocket = clientSocket;
_mySocketHandleInt64 = mySocket.Handle.ToInt64();
mySocketIO = new SocketIO(clientSocket, RecMode);
// Register for events
mySocketIO.TxMessageReceived += OnTxMessageReceived;
mySocketIO.MessageSent += OnMessageSent;
mySocketIO.dbMessageReceived += OndbMessageReceived;
}
public void StartListening()
{
mySocketIO.StartReceiving();
}
public void Close()
{
if (mySocketIO != null)
{
mySocketIO.Close();
mySocketIO = null;
}
try
{
mySocket.Close();
}
catch
{
// We're closing.. don't worry about it
}
}
public void SendMessage(int MessageNumber, int MessageType, string Message)
{
if (mySocket != null && mySocketIO != null)
{
try
{
mySocketIO.SendMessage(MessageNumber, MessageType, Message);
}
catch
{
// mySocketIO disposed inbetween check and call
}
}
else
{
// Raise socket faulted event
if (ccSocketFaulted != null)
ccSocketFaulted(this);
}
}
}
}
Some useful links:
This is where I started:
http://vadmyst.blogspot.com.au/2008/01/how-to-transfer-fixed-sized-data-with.html
http://vadmyst.blogspot.com.au/2008/03/part-2-how-to-transfer-fixed-sized-data.html
And..
C# Sockets and Multithreading
Cause a connected socket to accept new messages right after .BeginReceive?
http://nitoprograms.blogspot.com.au/2009/04/tcpip-net-sockets-faq.html
http://www.codeproject.com/Articles/83102/C-SocketAsyncEventArgs-High-Performance-Socket-Cod
I can't post my entire solution just now; there is a flaw in my server code I need to debug; plus there are parts which my employer may not want published. But i based my code on what Vadym had for variable length messages.
When a server gets ready to accept TCP connections, it creates a new TCP socket, Bind() it to a port and uses the Listen() method. When a connection request comes in, the Listen() method returns a new socket that the server and client use for communication. The server and client can pass data back and forth using Send() and Receive() at this point. If the client disconnects, the server's Receive() terminates with 0 bytes of data.
If you want to wait for another connection request once you've accepted the first connection (i.e., while you are interacting with the first client) this can be done. At this point, you'll need to use something like threads or asynchronous methods so you can handle more than one connection. Basically, you will be able to Accept() connection requests from your listening socket.
Mike