Simple Echo Server

I am using Visual J# 2005 Express Beta 2 to create a simple echo server. I have created the form and design and able am able to launch the program. I have created a RichTextbox to display the connections and 'echo's. The problem is when after starting the echo server by clicking on a button, the program stops responding. But the echo server is running in the background because I am able to connect to the echo server (localhost/port with telnet) and am able to "echo" messages. After the the telnet connection to the Echo Server is closed, the Echo server program starts responding and displays all the messages in the RichTextBox. And am able to start the echo server again. The program works and ends cleanly, but I want to be able to see the connections and echos as they are occuring
How can I get the echo server to show messages while the echo server is running and connections are coming in?

Does anyone have a sample code?

Below is a snippet from my button method. (I can also provide my complete code.)

privatevoid button2_Click(Object sender,System.EventArgs e){
richTextBox1.AppendText(
"EchoServer started. \n");

try{
ServerSocket s =newServerSocket(8008);
Socket incoming = s.accept();
richTextBox1.AppendText(
"Connected to: " + incoming.getInetAddress() +" at port: " + incoming.getLocalPort() +"\n");

BufferedReader in =newBufferedReader(newInputStreamReader(incoming.getInputStream()));

PrintWriter out =newPrintWriter(newOutputStreamWriter(incoming.getOutputStream()));

out.println("Hello! This is Java EchoServer. Enter BYE to exit.");
out.flush();

for (; ; )
{
String str = in.readLine();
if (str ==null)
{
break;
}
else
{
out.println(
"Echo: " + str);
out.flush();
richTextBox1.AppendText(
"Received: " + str +"\n");
if (str.trim().equals("BYE"))
break;
}
}
incoming.close();
}
catch (Exception err)
{
richTextBox1.AppendText(
"Error: " + err +"\n");
}
richTextBox1.AppendText(
"EchoServer stopped.\n");
}

Thanks,
kihtap

[4677 byte] By [kihap] at [2008-2-16]
# 1
Hi,
Your problem is that you are doing everything in the main thread (that's what i could make out from your problem description). The UI thread should not have any blocking/waiting or CPU instensive tasks because it makes UI nonresponsive. To avoid nonresponsiveness, do your server job in a seperate thread and keep UI thread (main thread) as free as possible.

You can create a new thread using System.Threading.Thread class. For ex...

System.Threading.Thread thrd = new System.Threading.Thread(ThreadStartFunc);

thrd.Start();

Then inside ThreadStartFunc do your server job. To update the textBox from this thread you can use textBox.BeginInvoke().

PLease post back if still you face any issues.

Thanks.

JaiprakashSharma at 2007-9-9 > top of Msdn Tech,Visual J#,Visual J# General...
# 2

Thanks for your help, but I am not able to run the program--

I created a new method ThreadStartFunc -->

public void ThreadStartFunc() throws InterruptedException

{

// code...
}
and right underneath it I have the button code -->

private
void button1_Click(Object sender, System.EventArgs e){
System.Threading.Thread thrd = new System.Threading.Thread(ThreadStartFunc);
thrd.Start();
}

But I keep getting this error:

Error 1 Name 'ThreadStartFunc' is not defined in current context

I added
"public System.Threading.Thread ThreadStartFunc;"
at the begining of my class right underneath the form button/textbox declarations, and the I get the following error.

Error 1 Cannot find constructor 'System.Threading.Thread(System.Threading.Thread)'

I also added "import System.Threading.*;" but am still getting the Error 1 Cannot find constructor 'System.Threading.Thread(System.Threading.Thread)' error.

Have I not created the methods properly?

Also I didn't follow where and how I should place the "textBox.BeginInvoke()."

Thanks.

kihtap at 2007-9-9 > top of Msdn Tech,Visual J#,Visual J# General...
# 3

OOps, you need to pass an instance of System.Threading.ThreadStart delegate to the constructor of System.Threading.Thread class as shown below...

public void Func1() {
System.Threading.Thread thread = new System.Threading.Thread(new
System
.Threading.ThreadStart(Func2));
}

public void Func2() { }
You will need to call "textBox.BeginInvoke()." inside Func2 to update the textbox control. You cannot update UI controls from any thread other than the Main window thread.
To know more about BeginInvoke please refer this
link.

Thanks.

JaiprakashSharma at 2007-9-9 > top of Msdn Tech,Visual J#,Visual J# General...
# 4

Okay this is what I have now:

I added "private delegate void RichTextBoxUpdateEventHandler(String message);"
in my class.

In my button method I have:

private void button1_Click(Object sender, System.EventArgs e)
{
System.Threading.Thread thrd = new System.Threading.Thread(new
System.Threading.ThreadStart(ThreadStartFunc));
thrd.Start();
}

I have my ThredStartFunc->

public void ThreadStartFunc() throws InterruptedException
{
...code...
String messageToLog = "MultiEchoServer started.";
UpdateRichTextBox(messageToLog);

...code...
}

I created a new method to handle data passed to the rich text box:

private
void UpdateRichTextBox(String message)
{
richTextBox1.BeginInvoke(
new RichTextBoxUpdateEventHandler(UpdateRichTextBox), // the method to call
new Object[] { message } // the list of arguments to pass );
}

But I get an error message that BeginInvoke is not called properly:

Error 1 Cannot find method 'BeginInvoke(RichTextBoxUpdateEventHandler, Object[])' in 'System.Windows.Forms.RichTextBox'

BeginInvoke is defined as-- BeginInvoke(System.Delegate method, Object[] args)

That is what I have written, RichTextBoxUpdateEventHandler, is a delegate defined in the class.

Why is this not working?

kihtap at 2007-9-9 > top of Msdn Tech,Visual J#,Visual J# General...
# 5
OK, in J# one need to add delegate attribute before declaration of the delegate as i have done in the following lines...

/** @delegate */
private
delegate void RichTextBoxUpdateEventHandler(String message);"

It should work for you now. Feel free to post back if you hit any other issue.

Thanks,
Jaiprakash

JaiprakashSharma at 2007-9-9 > top of Msdn Tech,Visual J#,Visual J# General...
# 6

Hi,
I will like to add few more lines about delegates in J#.
J# supports two kinds of delegates.

1. Delegate of VJ++ time - for backward compatibility with J++ and compatibility with java for smooth transition from java to .net world. For this class of delegates you need not annotate the declaration of delegate with /** @delegate */ attribute. Compiler knows that this delegate is J++ style delegate so emits the IL in such a way that these delegates derive from com.ms.lang.Delegate.

2. Delegates of .net world - If you annotate the declaration with /** @delegate */ attribute compiler understands that you want to declare a .net delegate deriving from System.Delegate class and emits the code accordingly.

To know more about j# delegates, please visit following links...

http://winfx.msdn.microsoft.com/library/default.asp?url=/library/en-us/dv_vjcon/html/586abfa8-55ab-45d0-b5c2-f765cf361bea.asp

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dv_vstechart/html/bjthedel.asp

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dv_vstechart/html/bjDelegatesInAction3.asp

Thanks.

JaiprakashSharma at 2007-9-9 > top of Msdn Tech,Visual J#,Visual J# General...
# 7
Kihtap,

I suggest you to have separate thread for Server and separate thread for each client request.

Following is the code sample to depict my point

public void ThreadStartFunc()
{
// Process client's request here
}

public void StartServer()
{
try
{
s = new ServerSocket(8008);
while (true)
{
incoming = s.accept();
System.Threading.Thread thrd = new
System.Threading.Thread(new ThreadStart(ThreadStartFunc));

thrd.Start();

}

}

catch (System.Exception ex)

{

// handle exception

}

richTextBox1.AppendText("EchoServer stopped.\n");

}

private void button1_Click(Object sender, System.EventArgs e)

{

richTextBox1.AppendText("EchoServer started. \n");

try

{

System.Threading.Thread thrd = new
System
.Threading.Thread(new ThreadStart(StartServer));

thrd.Start();

}

catch (Exception err)

{

// handle exception
}

}

If there are multiple connects then you might need to take care of synchronizing textbox.

RamakrishnaNeela at 2007-9-9 > top of Msdn Tech,Visual J#,Visual J# General...
# 8
I am trying to incorporate the information you gave me. Its kind of difficult to debug when the UI is not responding, so its hard to tell where its stuck.

I wanted to know you are passing the new connection (incoming) to the new thread (thrd) in your StartServer ex:
while (true)
{
incoming = s.accept();
System.Threading.Thread thrd = new
System.Threading.Thread(new ThreadStart(ThreadStartFunc));

thrd.Start();

}
Should I make a new class the handles the thread? And If I do that will I still be able to write back to the UI richTextbox from the other class?

Thanks for all help.

kihtap at 2007-9-9 > top of Msdn Tech,Visual J#,Visual J# General...
# 9
Hi,
Is your UI still hanging after using the pattern suggested by Ramakrishna? It should not hang now.
You are free to create as many classes as you feel required. Only thing to remember is taht if you want to update the textbox from any thread other than the thread which created the textbox then you have to use textBox.BeginInvoke(). That's what we have discussed before also.

Thanks.

JaiprakashSharma at 2007-9-9 > top of Msdn Tech,Visual J#,Visual J# General...