Sign in to follow this  
precious roy

Server client problem (C#)

Recommended Posts

hi all I have a problem with my code its a window form when i start listening my window freezes NOTE I can still connect to it. can anyone tell me why

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net;          // For IPAddress
using System.Net.Sockets;  // For TcpListener, TcpClient

namespace WindowsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Client();
        }
        private const int BUFSIZE = 32; // Size of receive buffer

        private void Client()
        {
            int ServerPort = Convert.ToInt32("1234");
            TcpListener listener = null;
            try
            {

                IPAddress ipAd = IPAddress.Parse("192.168.0.147"); //use local m/c IP address, and use the same in the client
                // Create a TCPListener to accept client connections
                //listener = new TcpListener(IPAddress.Any, ServerPort);
                listener = new TcpListener(ipAd, ServerPort);
                listener.Start();

            }
            catch (SocketException se)
            {
                Console.WriteLine(se.ErrorCode + ": " + se.Message);
                Environment.Exit(se.ErrorCode);
            }

            byte[] rcvBuffer = new byte[BUFSIZE]; // Receive buffer
            int bytesRcvd;                        // Received byte count
            textBox1.AppendText("The server is running at port " + "1234" + " ..." + "\n");
            textBox1.AppendText("And listening on Ip  :" + listener.LocalEndpoint + "\n");
            textBox1.AppendText("Waiting for a connection....." + "\n");

            for (; ; )
            { // Run forever, accepting and servicing connections

                TcpClient client = null;
                NetworkStream netStream = null;

                try
                {
                    client = listener.AcceptTcpClient(); // Get client connection
                    netStream = client.GetStream();
                    textBox1.AppendText("Handling client - " + "\n");

                    // Receive until client closes connection, indicated by 0 return value
                    int totalBytesEchoed = 0;
                    while ((bytesRcvd = netStream.Read(rcvBuffer, 0, rcvBuffer.Length)) > 0)
                    {
                        netStream.Write(rcvBuffer, 0, bytesRcvd);
                        totalBytesEchoed += bytesRcvd;
                    }
                    textBox1.AppendText("echoed " + totalBytesEchoed + " bytes." + "\n");

                    // Close the stream and socket. We are done with this client!
                    netStream.Close();
                    client.Close();

                }
                catch (Exception e)
                {
                    textBox1.AppendText(e.Message + "\n");
                    netStream.Close();
                }
            }
        }
    }
}


Share this post


Link to post
Share on other sites
Basically you are blocking the thread the form is created on with the .Read() call. You will want to either use asynchronous I/O (BeginRead + EndRead) or run the socket reading from a different thread than the form's thread.

Share this post


Link to post
Share on other sites
if i run it on a difrent thread how do you send the

textBox1.AppendText

i get this error

Cross-thread operation not valid: Control 'textBox1' accessed from a thread other than the thread it was created on.

[Edited by - precious roy on May 10, 2008 5:41:10 AM]

Share this post


Link to post
Share on other sites
You need to check if invoke is required - look up cross thread calls on Google and you should get an article with a decent explanation of what I mean.

Basically your thread is trying to access a property that was created on the applications main thread (a different thread) and you can't do this directly. Sorry I can't be of more help - very hung over.

James

Share this post


Link to post
Share on other sites
If you want to do that then you have to use Delegates in C#. Look up info on google on how to create a delegate. It ends up looking something like:

Delegate myDelegate
{
TextBox.DoStuff();
}


SeparateThread{

...Read();

form1.invoke(myDelegate);


}


Also, just note, it is generally frowned upon to manipulate UI code from a separate thread, although I do it using delegates and have yet to either run into a problem or have a really good explanation as to why you don't want to do that.

Share this post


Link to post
Share on other sites
Yes that's it - this:


private void SetText(string text)
{
// InvokeRequired required compares the thread ID of the
// calling thread to the thread ID of the creating thread.
// If these threads are different, it returns true.
if (this.textBox1.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SetText);
this.Invoke(d, new object[] { text });
}
else
{
this.textBox1.Text = text;
}
}




is what I was talking about earlier. When working with threads in WinForms you'll often hit this problem.

James

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this