472,142 Members | 1,189 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,142 software developers and data experts.

question about multithread c# socket server

Hello:
I write a multithread c# socket server,it is a winform application,there is a richtextbox control and button,when the button is click,the server begin to listen the socket port,waiting for a incoming connection,the relative code snipprt as following::

private IPAddress myIP=IPAddress.Parse("127.0.0.1");
private IPEndPoint myServer;
private Socket socket;
private Socket accSocket;
private System.Windows.Forms.Button button2;
private bool check;

private void button1_Click(object sender, System.EventArgs e)
{
check=true;
try
{
Thread thread =new Thread(new ThreadStart(accp));
thread.Start();
}
catch(Exception ee)
{
MessageBox.Show(ee.Message);
}
}

private void accp()
{
myServer=new IPEndPoint(myIP,Int32.Parse("20000"));
socket=new Socket(AddressFamily.InterNetwork,SocketType.Strea m,ProtocolType.Tcp);
socket.Bind(myServer);
socket.Listen(50);

while(true)
{
try
{
accSocket=socket.Accept();
if(accSocket.Connected)
{
Thread thread=new Thread(new ThreadStart(round));
thread.Start();
}
}
catch(Exception ee)
{
MessageBox.Show(ee.Message);
}
}
}

private void round()
{

Byte[] rec=new Byte[1024];
NetworkStream acceptStream=new NetworkStream(accSocket);

int i=0;
while((i=acceptStream.Read(rec,0,rec.Length))!=0)
{
string recMessage=System.Text.Encoding.Default.GetString( rec);
rec=new Byte[1024];
this.richTextBox1.AppendText(recMessage);
}

}
……………………………………….
………………………………………


In order to test the server,I write a multithread client too,there is only one button in the form,when it is clicked,four threads is generated to connect the server simultaneously,each thread write one line to the server socket.code as:

private IPAddress myIP;
private IPEndPoint myServer;
private Socket socket;

private void button1_Click(object sender, System.EventArgs e)
{
for(int i=0;i<4;i++)
{
Thread thread=new Thread(new ThreadStart(round));
thread.Start();
thread.Join();
}
}

private void round()
{
try
{
myIP=IPAddress.Parse("127.0.0.1");
myServer=new IPEndPoint(myIP,Int32.Parse("20000"));
socket=new Socket(AddressFamily.InterNetwork,SocketType.Strea m,ProtocolType.Tcp);
socket.Connect(myServer);
NetworkStream netStream=new NetworkStream(socket);

Byte[] byteMessage=new Byte[640];
string sendMessage="大家好!!!!!\r\n";
byteMessage=System.Text.Encoding.Default.GetBytes( sendMessage.ToCharArray());
// socket.Send(byteMessage,byteMessage.Length,0);
netStream.Write(byteMessage,0,byteMessage.Length);
netStream.Flush();
netStream.Close();
socket.Close();
}
catch(Exception ee)
{
MessageBox.Show(ee.Message);
}

}

As you can see,when I click the button in the client side,I should see four lines is printed in the server side.but in fact,I can’t,I can only see one line,sometimes two or three lines,by my tracing,I found they always come from the last several threads.if I modify the button click event in the client as following(add sleep between the threads),it works well,that is I can see four lines every time in the server:
private void button1_Click(object sender, System.EventArgs e)
{
for(int i=0;i<4;i++)
{
Thread thread=new Thread(new ThreadStart(round));
thread.Start();
thread.Join();
Thread.Sleep(100);
}
}

If I modify the timeout param of the sleep method to lower and lower, the mentioned problem occur again.i also write a java multithread server, it works well to the simuteneous thread connection.
Why c# socket server can’t handle the simultaneous access?is it a bug?by comparing the java server and c# server,I also found that the java server is faster then c# server.

Any instruction?Thank you.
Nov 16 '05 #1
4 6944
Hello!

For instance you don't respect that the rich text box may only be dealt with
by the STA thread which created it.

Have you generally considered to use asynchronous sockets instead of your
own explicit thread handling?
Best regards,

Henrik Dahl

"zbcong" <zb****@discussions.microsoft.com> wrote in message
news:5C**********************************@microsof t.com...
Hello:
I write a multithread c# socket server,it is a winform application,there is a richtextbox control and button,when the button is click,the server
begin to listen the socket port,waiting for a incoming connection,the
relative code snipprt as following::
private IPAddress myIP=IPAddress.Parse("127.0.0.1");
private IPEndPoint myServer;
private Socket socket;
private Socket accSocket;
private System.Windows.Forms.Button button2;
private bool check;

private void button1_Click(object sender, System.EventArgs e)
{
check=true;
try
{
Thread thread =new Thread(new ThreadStart(accp));
thread.Start();
}
catch(Exception ee)
{
MessageBox.Show(ee.Message);
}
}

private void accp()
{
myServer=new IPEndPoint(myIP,Int32.Parse("20000"));
socket=new Socket(AddressFamily.InterNetwork,SocketType.Strea m,ProtocolType.Tcp); socket.Bind(myServer);
socket.Listen(50);

while(true)
{
try
{
accSocket=socket.Accept();
if(accSocket.Connected)
{
Thread thread=new Thread(new ThreadStart(round));
thread.Start();
}
}
catch(Exception ee)
{
MessageBox.Show(ee.Message);
}
}
}

private void round()
{

Byte[] rec=new Byte[1024];
NetworkStream acceptStream=new NetworkStream(accSocket);

int i=0;
while((i=acceptStream.Read(rec,0,rec.Length))!=0)
{
string recMessage=System.Text.Encoding.Default.GetString( rec);
rec=new Byte[1024];
this.richTextBox1.AppendText(recMessage);
}

}
................
...............


In order to test the server,I write a multithread client too,there is only one button in the form,when it is clicked,four threads is generated to
connect the server simultaneously,each thread write one line to the server
socket.code as:
private IPAddress myIP;
private IPEndPoint myServer;
private Socket socket;

private void button1_Click(object sender, System.EventArgs e)
{
for(int i=0;i<4;i++)
{
Thread thread=new Thread(new ThreadStart(round));
thread.Start();
thread.Join();
}
}

private void round()
{
try
{
myIP=IPAddress.Parse("127.0.0.1");
myServer=new IPEndPoint(myIP,Int32.Parse("20000"));
socket=new Socket(AddressFamily.InterNetwork,SocketType.Strea m,ProtocolType.Tcp); socket.Connect(myServer);
NetworkStream netStream=new NetworkStream(socket);

Byte[] byteMessage=new Byte[640];
string sendMessage="???!!!!!\r\n";
byteMessage=System.Text.Encoding.Default.GetBytes( sendMessage.ToCharArray())
; // socket.Send(byteMessage,byteMessage.Length,0);
netStream.Write(byteMessage,0,byteMessage.Length);
netStream.Flush();
netStream.Close();
socket.Close();
}
catch(Exception ee)
{
MessageBox.Show(ee.Message);
}

}

As you can see,when I click the button in the client side,I should see four lines is printed in the server side.but in fact,I can't,I can only see
one line,sometimes two or three lines,by my tracing,I found they always come
from the last several threads.if I modify the button click event in the
client as following(add sleep between the threads),it works well,that is I
can see four lines every time in the server:

private void button1_Click(object sender, System.EventArgs e)
{
for(int i=0;i<4;i++)
{
Thread thread=new Thread(new ThreadStart(round));
thread.Start();
thread.Join();
Thread.Sleep(100);
}
}

If I modify the timeout param of the sleep method to lower and lower, the mentioned problem occur again.i also write a java multithread server, it
works well to the simuteneous thread connection. Why c# socket server can't handle the simultaneous access?is it a bug?by comparing the java server and c# server,I also found that the java server is
faster then c# server.
Any instruction?Thank you.

Nov 16 '05 #2
no,it is not the problem of rich text box,if you replace "richTextBox1.AppendText(recMessage)" with "Console.WriteLine(recMessage)" in the serverside,you can only see ONE line printed every time the button is clicked,why?





"Henrik Dahl" wrote:
Hello!

For instance you don't respect that the rich text box may only be dealt with
by the STA thread which created it.

Have you generally considered to use asynchronous sockets instead of your
own explicit thread handling?
Best regards,

Henrik Dahl

"zbcong" <zb****@discussions.microsoft.com> wrote in message
news:5C**********************************@microsof t.com...
Hello:
I write a multithread c# socket server,it is a winform application,there

is a richtextbox control and button,when the button is click,the server
begin to listen the socket port,waiting for a incoming connection,the
relative code snipprt as following::

private IPAddress myIP=IPAddress.Parse("127.0.0.1");
private IPEndPoint myServer;
private Socket socket;
private Socket accSocket;
private System.Windows.Forms.Button button2;
private bool check;

private void button1_Click(object sender, System.EventArgs e)
{
check=true;
try
{
Thread thread =new Thread(new ThreadStart(accp));
thread.Start();
}
catch(Exception ee)
{
MessageBox.Show(ee.Message);
}
}

private void accp()
{
myServer=new IPEndPoint(myIP,Int32.Parse("20000"));
socket=new

Socket(AddressFamily.InterNetwork,SocketType.Strea m,ProtocolType.Tcp);
socket.Bind(myServer);
socket.Listen(50);

while(true)
{
try
{
accSocket=socket.Accept();
if(accSocket.Connected)
{
Thread thread=new Thread(new ThreadStart(round));
thread.Start();
}
}
catch(Exception ee)
{
MessageBox.Show(ee.Message);
}
}
}

private void round()
{

Byte[] rec=new Byte[1024];
NetworkStream acceptStream=new NetworkStream(accSocket);

int i=0;
while((i=acceptStream.Read(rec,0,rec.Length))!=0)
{
string recMessage=System.Text.Encoding.Default.GetString( rec);
rec=new Byte[1024];
this.richTextBox1.AppendText(recMessage);
}

}
................
...............


In order to test the server,I write a multithread client too,there is only

one button in the form,when it is clicked,four threads is generated to
connect the server simultaneously,each thread write one line to the server
socket.code as:

private IPAddress myIP;
private IPEndPoint myServer;
private Socket socket;

private void button1_Click(object sender, System.EventArgs e)
{
for(int i=0;i<4;i++)
{
Thread thread=new Thread(new ThreadStart(round));
thread.Start();
thread.Join();
}
}

private void round()
{
try
{
myIP=IPAddress.Parse("127.0.0.1");
myServer=new IPEndPoint(myIP,Int32.Parse("20000"));
socket=new

Socket(AddressFamily.InterNetwork,SocketType.Strea m,ProtocolType.Tcp);
socket.Connect(myServer);
NetworkStream netStream=new NetworkStream(socket);

Byte[] byteMessage=new Byte[640];
string sendMessage="???!!!!!\r\n";

byteMessage=System.Text.Encoding.Default.GetBytes( sendMessage.ToCharArray())
;
// socket.Send(byteMessage,byteMessage.Length,0);
netStream.Write(byteMessage,0,byteMessage.Length);
netStream.Flush();
netStream.Close();
socket.Close();
}
catch(Exception ee)
{
MessageBox.Show(ee.Message);
}

}

As you can see,when I click the button in the client side,I should see

four lines is printed in the server side.but in fact,I can't,I can only see
one line,sometimes two or three lines,by my tracing,I found they always come
from the last several threads.if I modify the button click event in the
client as following(add sleep between the threads),it works well,that is I
can see four lines every time in the server:


private void button1_Click(object sender, System.EventArgs e)
{
for(int i=0;i<4;i++)
{
Thread thread=new Thread(new ThreadStart(round));
thread.Start();
thread.Join();
Thread.Sleep(100);
}
}

If I modify the timeout param of the sleep method to lower and lower, the

mentioned problem occur again.i also write a java multithread server, it
works well to the simuteneous thread connection.
Why c# socket server can't handle the simultaneous access?is it a bug?by

comparing the java server and c# server,I also found that the java server is
faster then c# server.

Any instruction?Thank you.


Nov 16 '05 #3
zbcong wrote:
no,it is not the problem of rich text box,if you replace "richTextBox1.AppendText(recMessage)" with "Console.WriteLine(recMessage)" in the serverside,you can only see ONE line printed every time the button is clicked,why?
No, it is not the problem of the rich text box. As the previous response
said, it is the problem of thread safety. The RTB is not threadsafe, and
must be updated in the thread that created the RTB only.
Console.WriteLine() is threadsafe. Thus you get what you expect. What
you need is a way to update in the creating thread:
class MyForm:Form
{
public void Append(String msg)
{
if( InvokeRequired )
BeginInvoke(new MyDelegate(InvokedAppendFunc),
new object[] {msg});
else
DoAppend(msg);
}
private void InvokedAppendFunc(String msg)
{
DoAppend(msg);
}
private void DoAppend(String msg)
{
richtextbox1.Append(msg);
}

A simple locking wouldn't work:
lock(richtextbox1)
richtextbox1.Append(msg);

because none of the code in the RTB does this, and you need threadsafety
support to make it work. So the above Invoke procedure is the only way.

Also, consider the previous posters async socket suggestion. It uses
threads under the covers, and you do not need any explicit thread
management (other than remembering you are in a subthread and need to
keep thread safety in mind.)

David Logan




"Henrik Dahl" wrote:

Hello!

For instance you don't respect that the rich text box may only be dealt with
by the STA thread which created it.

Have you generally considered to use asynchronous sockets instead of your
own explicit thread handling?
Best regards,

Henrik Dahl

"zbcong" <zb****@discussions.microsoft.com> wrote in message
news:5C**********************************@micros oft.com...
Hello:
I write a multithread c# socket server,it is a winform application,there


is a richtextbox control and button,when the button is click,the server
begin to listen the socket port,waiting for a incoming connection,the
relative code snipprt as following::
private IPAddress myIP=IPAddress.Parse("127.0.0.1");
private IPEndPoint myServer;
private Socket socket;
private Socket accSocket;
private System.Windows.Forms.Button button2;
private bool check;

private void button1_Click(object sender, System.EventArgs e)
{
check=true;
try
{
Thread thread =new Thread(new ThreadStart(accp));
thread.Start();
}
catch(Exception ee)
{
MessageBox.Show(ee.Message);
}
}

private void accp()
{
myServer=new IPEndPoint(myIP,Int32.Parse("20000"));
socket=new


Socket(AddressFamily.InterNetwork,SocketType.Str eam,ProtocolType.Tcp);
socket.Bind(myServer);
socket.Listen(50);

while(true)
{
try
{
accSocket=socket.Accept();
if(accSocket.Connected)
{
Thread thread=new Thread(new ThreadStart(round));
thread.Start();
}
}
catch(Exception ee)
{
MessageBox.Show(ee.Message);
}
}
}

private void round()
{

Byte[] rec=new Byte[1024];
NetworkStream acceptStream=new NetworkStream(accSocket);

int i=0;
while((i=acceptStream.Read(rec,0,rec.Length))!= 0)
{
string recMessage=System.Text.Encoding.Default.GetString( rec);
rec=new Byte[1024];
this.richTextBox1.AppendText(recMessage);
}

}
................
...............


In order to test the server,I write a multithread client too,there is only


one button in the form,when it is clicked,four threads is generated to
connect the server simultaneously,each thread write one line to the server
socket.code as:


private IPAddress myIP;
private IPEndPoint myServer;
private Socket socket;

private void button1_Click(object sender, System.EventArgs e)
{
for(int i=0;i<4;i++)
{
Thread thread=new Thread(new ThreadStart(round));
thread.Start();
thread.Join();
}
}

private void round()
{
try
{
myIP=IPAddress.Parse("127.0.0.1");
myServer=new IPEndPoint(myIP,Int32.Parse("20000"));
socket=new


Socket(AddressFamily.InterNetwork,SocketType.Str eam,ProtocolType.Tcp);
socket.Connect(myServer);
NetworkStream netStream=new NetworkStream(socket);

Byte[] byteMessage=new Byte[640];
string sendMessage="???!!!!!\r\n";


byteMessage=System.Text.Encoding.Default.GetByte s(sendMessage.ToCharArray())
;
// socket.Send(byteMessage,byteMessage.Length,0);
netStream.Write(byteMessage,0,byteMessage.Lengt h);
netStream.Flush();
netStream.Close();
socket.Close();
}
catch(Exception ee)
{
MessageBox.Show(ee.Message);
}

}

As you can see,when I click the button in the client side,I should see


four lines is printed in the server side.but in fact,I can't,I can only see
one line,sometimes two or three lines,by my tracing,I found they always come
from the last several threads.if I modify the button click event in the
client as following(add sleep between the threads),it works well,that is I
can see four lines every time in the server:

private void button1_Click(object sender, System.EventArgs e)
{
for(int i=0;i<4;i++)
{
Thread thread=new Thread(new ThreadStart(round));
thread.Start();
thread.Join();
Thread.Sleep(100);
}
}

If I modify the timeout param of the sleep method to lower and lower, the


mentioned problem occur again.i also write a java multithread server, it
works well to the simuteneous thread connection.
Why c# socket server can't handle the simultaneous access?is it a bug?by


comparing the java server and c# server,I also found that the java server is
faster then c# server.
Any instruction?Thank you.


Nov 16 '05 #4
Hi,

I haven't worked with sockets, but your server is not thread safe at
all.

Please, read inline:


private void accp()
{
myServer=new IPEndPoint(myIP,Int32.Parse("20000"));
socket=new Socket(AddressFamily.InterNetwork,SocketType.Strea m,ProtocolType.Tcp);
socket.Bind(myServer);
socket.Listen(50);

while(true)
{
try
{
accSocket=socket.Accept();
1. now here you set a field variable accSocket to the current accepted
socket. And start a thread which deals it that variable. And then you go
to grab the next accepted socket. And you may get it even before the
working thread is started. And you replace the same variable, so the
working method in the started thread will see the new connected socket,
not the previous one, for which was started.
if(accSocket.Connected)
{
Thread thread=new Thread(new ThreadStart(round));
thread.Start();
}
}
catch(Exception ee)
{
MessageBox.Show(ee.Message);
}
}
}

private void round()
{

Byte[] rec=new Byte[1024];
NetworkStream acceptStream=new NetworkStream(accSocket);
??? what exact connection you are dealing with here? With this
implementation you are always using the last accepted one in the other
thread.


int i=0;
while((i=acceptStream.Read(rec,0,rec.Length))!=0)
{
string recMessage=System.Text.Encoding.Default.GetString( rec);
rec=new Byte[1024];
this.richTextBox1.AppendText(recMessage);
}

}


You can make your server thread safe either by using the async socket
handling, by something like this:
class SocketReadingThread
{
private readonly Socket accSocket;

public SocketReadingThread(Socket acceptedSocket)
{
this.accSocket = acceptedSocket;
}

public void Rount()
{
..... your implementation goes here
}
}

There is a possible memory leak as well, I do not see where you close
the accepted socket or the NetworkStream.

Also, as others have mentioned, you can not write directly in the RTB
from different threads. All windows controls are not thread safe. You
have to use the Invoke method from the threads, so the writing is
correct.

Ion Skeet has a wonderful article about threads. I wish he had wrote 1
year ago ... :)

http://www.yoda.arachsys.com/csharp/multithreading.html

Sunny
Nov 16 '05 #5

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

2 posts views Thread by zhebincong | last post: by
1 post views Thread by John Sheppard | last post: by
5 posts views Thread by Naveen Mukkelli | last post: by
4 posts views Thread by Crirus | last post: by
2 posts views Thread by djc | last post: by
4 posts views Thread by Engineerik | last post: by
2 posts views Thread by Dave Dean | last post: by
2 posts views Thread by Ali Hamad | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.