Need help on chat between two computers
-
I have used this tutorial to make a chat: http://www.youtube.com/watch?v=BDVfpPq3weo[^] It works on the same computer but not between two. The problem seem so be that I need more than one thread. I get Cross-thread operation not valid.
No, the problem is the reverse of that: "Cross-thread operation not valid" means that you are executing code on one thread that can only be executed on a different thread: normally, this occurs when you try to update a control from a different thread to that from which it was created (which must be the UI thread), either in a BackgoundWorker, a Thread instance or in the handler of a communications class that uses threading to handle it's events (the SerialPort does this for example). Check your code: you may just have to start invoking the control instead of accessing it directly. For example:
private void AddNewTab(string tabName) { if (InvokeRequired) { Invoke(new MethodInvoker(delegate { AddNewTab(tabName); })); } else { TabPage tp = new TabPage(tabName); myTabControl.TabPages.Add(tp); } }
Those who fail to learn history are doomed to repeat it. --- George Santayana (December 16, 1863 – September 26, 1952) Those who fail to clear history are doomed to explain it. --- OriginalGriff (February 24, 1959 – ∞)
-
No, the problem is the reverse of that: "Cross-thread operation not valid" means that you are executing code on one thread that can only be executed on a different thread: normally, this occurs when you try to update a control from a different thread to that from which it was created (which must be the UI thread), either in a BackgoundWorker, a Thread instance or in the handler of a communications class that uses threading to handle it's events (the SerialPort does this for example). Check your code: you may just have to start invoking the control instead of accessing it directly. For example:
private void AddNewTab(string tabName) { if (InvokeRequired) { Invoke(new MethodInvoker(delegate { AddNewTab(tabName); })); } else { TabPage tp = new TabPage(tabName); myTabControl.TabPages.Add(tp); } }
Those who fail to learn history are doomed to repeat it. --- George Santayana (December 16, 1863 – September 26, 1952) Those who fail to clear history are doomed to explain it. --- OriginalGriff (February 24, 1959 – ∞)
Not sure I understand...Could you show how to change my code? This is my code:
private void Form1_Load(object sender, EventArgs e)
{
//Set up socket
sck = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
sck.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);//Get user IP txtLocalIP.Text = GetLocalIP(); txtRemoteIP.Text = GetLocalIP(); } private string GetLocalIP() { IPHostEntry host; host = Dns.GetHostEntry(Dns.GetHostName()); foreach (IPAddress ip in host.AddressList) { if (ip.AddressFamily == AddressFamily.InterNetwork) return ip.ToString(); } return "127.0.0.1"; } private void MessageCallBack(IAsyncResult aResult) { try { byte\[\] receivedData = new byte\[1500\]; receivedData = (byte\[\])aResult.AsyncState; //Converting byte{\] to string ASCIIEncoding aEncoding = new ASCIIEncoding(); string receivedMessage = aEncoding.GetString(receivedData); //Adding this messegage into ListBox listMessage.Items.Add("Friend: " + receivedMessage); buffer = new byte\[1500\]; sck.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref epRemote, new AsyncCallback(MessageCallBack), buffer); } catch (Exception ex) { MessageBox.Show(ex.ToString()); } } private void btnConnect\_Click(object sender, EventArgs e) { //Binding socket epLocal = new IPEndPoint(IPAddress.Parse(txtLocalIP.Text), Convert.ToInt32(txtLocalPort.Text)); sck.Bind(epLocal); //Connecting to remote IP epRemote = new IPEndPoint(IPAddress.Parse(txtRemoteIP.Text), Convert.ToInt32(txtRemotePort.Text)); sck.Connect(epRemote); //Listen to specific port buffer = new byte\[1500\]; sck.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref epRemote, new AsyncCallback(MessageCallBack), buffer); } private void btnSend\_Click(object sender, EventArgs e) { //Convert string message to
-
Not sure I understand...Could you show how to change my code? This is my code:
private void Form1_Load(object sender, EventArgs e)
{
//Set up socket
sck = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
sck.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);//Get user IP txtLocalIP.Text = GetLocalIP(); txtRemoteIP.Text = GetLocalIP(); } private string GetLocalIP() { IPHostEntry host; host = Dns.GetHostEntry(Dns.GetHostName()); foreach (IPAddress ip in host.AddressList) { if (ip.AddressFamily == AddressFamily.InterNetwork) return ip.ToString(); } return "127.0.0.1"; } private void MessageCallBack(IAsyncResult aResult) { try { byte\[\] receivedData = new byte\[1500\]; receivedData = (byte\[\])aResult.AsyncState; //Converting byte{\] to string ASCIIEncoding aEncoding = new ASCIIEncoding(); string receivedMessage = aEncoding.GetString(receivedData); //Adding this messegage into ListBox listMessage.Items.Add("Friend: " + receivedMessage); buffer = new byte\[1500\]; sck.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref epRemote, new AsyncCallback(MessageCallBack), buffer); } catch (Exception ex) { MessageBox.Show(ex.ToString()); } } private void btnConnect\_Click(object sender, EventArgs e) { //Binding socket epLocal = new IPEndPoint(IPAddress.Parse(txtLocalIP.Text), Convert.ToInt32(txtLocalPort.Text)); sck.Bind(epLocal); //Connecting to remote IP epRemote = new IPEndPoint(IPAddress.Parse(txtRemoteIP.Text), Convert.ToInt32(txtRemotePort.Text)); sck.Connect(epRemote); //Listen to specific port buffer = new byte\[1500\]; sck.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref epRemote, new AsyncCallback(MessageCallBack), buffer); } private void btnSend\_Click(object sender, EventArgs e) { //Convert string message to
Where do you get the error? Which line?
Those who fail to learn history are doomed to repeat it. --- George Santayana (December 16, 1863 – September 26, 1952) Those who fail to clear history are doomed to explain it. --- OriginalGriff (February 24, 1959 – ∞)
-
Not sure I understand...Could you show how to change my code? This is my code:
private void Form1_Load(object sender, EventArgs e)
{
//Set up socket
sck = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
sck.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);//Get user IP txtLocalIP.Text = GetLocalIP(); txtRemoteIP.Text = GetLocalIP(); } private string GetLocalIP() { IPHostEntry host; host = Dns.GetHostEntry(Dns.GetHostName()); foreach (IPAddress ip in host.AddressList) { if (ip.AddressFamily == AddressFamily.InterNetwork) return ip.ToString(); } return "127.0.0.1"; } private void MessageCallBack(IAsyncResult aResult) { try { byte\[\] receivedData = new byte\[1500\]; receivedData = (byte\[\])aResult.AsyncState; //Converting byte{\] to string ASCIIEncoding aEncoding = new ASCIIEncoding(); string receivedMessage = aEncoding.GetString(receivedData); //Adding this messegage into ListBox listMessage.Items.Add("Friend: " + receivedMessage); buffer = new byte\[1500\]; sck.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref epRemote, new AsyncCallback(MessageCallBack), buffer); } catch (Exception ex) { MessageBox.Show(ex.ToString()); } } private void btnConnect\_Click(object sender, EventArgs e) { //Binding socket epLocal = new IPEndPoint(IPAddress.Parse(txtLocalIP.Text), Convert.ToInt32(txtLocalPort.Text)); sck.Bind(epLocal); //Connecting to remote IP epRemote = new IPEndPoint(IPAddress.Parse(txtRemoteIP.Text), Convert.ToInt32(txtRemotePort.Text)); sck.Connect(epRemote); //Listen to specific port buffer = new byte\[1500\]; sck.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref epRemote, new AsyncCallback(MessageCallBack), buffer); } private void btnSend\_Click(object sender, EventArgs e) { //Convert string message to
larsp777 wrote:
listMessage.Items.Add("Friend: " + receivedMessage);
I'm guessing that's the line that's causing the problem. The callback method will be called on a background thread; you will need to use
InvokeRequired
andInvoke
to get back to the UI thread when you want to access the form's controls.Invoke((Func<object, int>)listMessage.Items.Add, "Friend: " + receivedMessage);
"These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer
-
larsp777 wrote:
listMessage.Items.Add("Friend: " + receivedMessage);
I'm guessing that's the line that's causing the problem. The callback method will be called on a background thread; you will need to use
InvokeRequired
andInvoke
to get back to the UI thread when you want to access the form's controls.Invoke((Func<object, int>)listMessage.Items.Add, "Friend: " + receivedMessage);
"These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer
-
Where do you get the error? Which line?
Those who fail to learn history are doomed to repeat it. --- George Santayana (December 16, 1863 – September 26, 1952) Those who fail to clear history are doomed to explain it. --- OriginalGriff (February 24, 1959 – ∞)
Ok... The other guy whose thread I can´t se now wrote: I'm guessing that's the line that's causing the problem. The callback method will be called on a background thread; you will need to use InvokeRequired and Invoke to get back to the UI thread when you want to access the form's controls. Invoke((Action<object>)listMessage.Items.Add, "Friend: " + receivedMessage); I Think he was right about the line. Tried to do change the line accordingly but got an error:
int System.Windows.Forms.ListBox.ObjectCollection.Add(object)' has the wrong return type
-
Where do you get the error? Which line?
Those who fail to learn history are doomed to repeat it. --- George Santayana (December 16, 1863 – September 26, 1952) Those who fail to clear history are doomed to explain it. --- OriginalGriff (February 24, 1959 – ∞)
-
Ok... The other guy whose thread I can´t se now wrote: I'm guessing that's the line that's causing the problem. The callback method will be called on a background thread; you will need to use InvokeRequired and Invoke to get back to the UI thread when you want to access the form's controls. Invoke((Action<object>)listMessage.Items.Add, "Friend: " + receivedMessage); I Think he was right about the line. Tried to do change the line accordingly but got an error:
int System.Windows.Forms.ListBox.ObjectCollection.Add(object)' has the wrong return type
larsp777 wrote:
int System.Windows.Forms.ListBox.ObjectCollection.Add(object)' has the wrong return type
Whoops - didn't notice that the method returned an
int
. The delegate type will need to be aFunc<object, int>
instead of anAction<object>
.Invoke((Func<object, int>)listMessage.Items.Add, "Friend: " + receivedMessage);
"These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer
-
larsp777 wrote:
int System.Windows.Forms.ListBox.ObjectCollection.Add(object)' has the wrong return type
Whoops - didn't notice that the method returned an
int
. The delegate type will need to be aFunc<object, int>
instead of anAction<object>
.Invoke((Func<object, int>)listMessage.Items.Add, "Friend: " + receivedMessage);
"These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer
:thumbsup:
Those who fail to learn history are doomed to repeat it. --- George Santayana (December 16, 1863 – September 26, 1952) Those who fail to clear history are doomed to explain it. --- OriginalGriff (February 24, 1959 – ∞)
-
larsp777 wrote:
int System.Windows.Forms.ListBox.ObjectCollection.Add(object)' has the wrong return type
Whoops - didn't notice that the method returned an
int
. The delegate type will need to be aFunc<object, int>
instead of anAction<object>
.Invoke((Func<object, int>)listMessage.Items.Add, "Friend: " + receivedMessage);
"These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer
-
I have used this tutorial to make a chat: http://www.youtube.com/watch?v=BDVfpPq3weo[^] It works on the same computer but not between two. The problem seem so be that I need more than one thread. I get Cross-thread operation not valid.
-
No, the problem is the reverse of that: "Cross-thread operation not valid" means that you are executing code on one thread that can only be executed on a different thread: normally, this occurs when you try to update a control from a different thread to that from which it was created (which must be the UI thread), either in a BackgoundWorker, a Thread instance or in the handler of a communications class that uses threading to handle it's events (the SerialPort does this for example). Check your code: you may just have to start invoking the control instead of accessing it directly. For example:
private void AddNewTab(string tabName) { if (InvokeRequired) { Invoke(new MethodInvoker(delegate { AddNewTab(tabName); })); } else { TabPage tp = new TabPage(tabName); myTabControl.TabPages.Add(tp); } }
Those who fail to learn history are doomed to repeat it. --- George Santayana (December 16, 1863 – September 26, 1952) Those who fail to clear history are doomed to explain it. --- OriginalGriff (February 24, 1959 – ∞)
-
Sorry Rahul, but it's a huge subject - I couldn't begin to do it justice in a small text box! :laugh: There are some good tutorials out there which explain threading and the UI pretty well: http://stuff.seans.com/2009/05/21/net-basics-do-work-in-background-thread-to-keep-gui-responsive/[^] (Backgound and why to thread) http://www.dreamincode.net/forums/topic/246911-c%23-multi-threading-in-a-gui-environment/[^] (Fairly advanced) But basically when you start to use multiple threads you can't touch any controls, except from the thread that created them - which is called the UI thread (for User Interface) and is the original thread the form started on. If you try, you will get a "cross-threading" error telling you not to do that. The only way to get round it is to Invoke the control - which basically requests the UI thread to do the work for you. Have a look at the BackgroundWorker thread - it provides a way to update the display without invoking via the ProgressChanged event, which is executed on the original thread.
Those who fail to learn history are doomed to repeat it. --- George Santayana (December 16, 1863 – September 26, 1952) Those who fail to clear history are doomed to explain it. --- OriginalGriff (February 24, 1959 – ∞)
-
larsp777 wrote:
int System.Windows.Forms.ListBox.ObjectCollection.Add(object)' has the wrong return type
Whoops - didn't notice that the method returned an
int
. The delegate type will need to be aFunc<object, int>
instead of anAction<object>
.Invoke((Func<object, int>)listMessage.Items.Add, "Friend: " + receivedMessage);
"These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer
-
Do you know if there is a simple way for a third person can listen in what the others are Writing. (only has to listen to the sender) I am making an application where you should be able to simulate someone eavesdropping the conversation.
If all the computers are on the same LAN, you could use the broadcast address so that any computer can pick up the messages: Broadcasting Using Socket-Oriented Approach[^] If they're on different networks, or you don't want the overhead associated with broadcasting, then you'll need to use multicasting: IP Multicasting in C#[^]
"These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer
-
If all the computers are on the same LAN, you could use the broadcast address so that any computer can pick up the messages: Broadcasting Using Socket-Oriented Approach[^] If they're on different networks, or you don't want the overhead associated with broadcasting, then you'll need to use multicasting: IP Multicasting in C#[^]
"These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer