Click to See Complete Forum and Search --> : Halt At Socket.Receive() Statement


yccheok
December 9th, 2002, 04:30 AM
i had build a light weighted http server and recently realize that there is some bugs inside.

in my constructor, i initialize the TcpListener and the thread for receiving incoming request as follow:
----------------------------------
myListener = new TcpListener(port);
myListener.Start();

//start the thread which calls the method 'StartListen'
myThread = new Thread(new ThreadStart(StartListen));
myThread.Start() ;
----------------------------------

in my StartListen
----------------------------------
while(isRunnable)
{
//Accept a new connection
Socket mySocket = myListener.AcceptSocket() ;

if(mySocket.Connected)
{
//make a byte array and receive data from the client
Byte[] bReceive = new Byte[1024] ;

int i = mySocket.Receive(bReceive,bReceive.Length,0); //BUGS??
// rest of the code goes here
----------------------------------
sometimes, when i use a web broswer making an HTTP/GET request, my web broswer takes 5 minutes to download the contents from the computer that run light weighted server(LWS) and still get no responde. it seems that it can establish a TCP/IP connection to the LWS but get no response from the LWS.

finally, i realize that LWS will halt at the line.
-----------------------------------
int i = mySocket.Receive(bReceive,bReceive.Length,0); //BUGS??
-----------------------------------

this happen "sometimes". where "sometimes" LWS works fine and "sometimes" LWS dont

can anyone point me out how can i solve this problem? thank you in advance.

regards
yccheok

MartinL
December 9th, 2002, 05:27 AM
It is normal... Your server is awaiting some data from the client... However your client doesn't send these date...

Client is also waiting for response from the server. However server is waiting data from the client, so deadlock occured.

That above can occure when you are not correctly parse and process query from the client. Imagine that the client sends you HTTP GET request. The server gets this request, parses it and process the request. The server that sends some response, which is wrong or is not full. Client waits for whole response. So it is waiting for next data.

That is just a clue... I don't have enough information about your project and its architecture to answer you more specific...

Martin

yccheok
December 9th, 2002, 11:54 PM
is it possible that i solve this problem using SocketOptionName.ReceiveTimeout?

i obtain a socket through TcpListener using:
Socket mySocket = myListener.AcceptSocket() ;//myListener is TcpListener

sometimes, i realize that my program will halt at line:
int i = mySocket.Receive(bReceive,bReceive.Length,0) ;

hence, i was thinking to set a receive timeout option, my questions is
(1)is this the correct method
mySocket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.ReceiveTimeout, 1000)

i put SocketOptionLevel as SocketOptionLevel.Tcp, is it correct?

(2)what will happen when the program come to line
int i = mySocket.Receive(bReceive,bReceive.Length,0) ;

and after 1000 miliseconds and still have not received anything. where will the program execution go?

thank you.

regards
yccheok

MartinL
December 10th, 2002, 10:37 AM
I don't think that setting receive timeout will solve the problem. However, you can try it...

1.) yes, it is correct method. All HTTP queries are done through TCP protocol...

2.) I don't know. There are two possibilities:
- exception signilizing that timeout occured will be thrown
- Receive() methods returns with zero return value
Check the documentation...

However, I really think that the problem is in processing the request and sending data back to the client. Not in the Receive function...

I realized the same problem (Receive() methods block the thread) the last time I wrote something as proxy server... The problem was in incorrect relaying between client and server. Client wants to send more data as I received by the first call to clientSocket.Recieve(), however I allready has been waiting for response from the server. So the call to serverSocket.Receive() block the tread...

Martin

yccheok
December 11th, 2002, 04:21 AM
hi, here is the solution i get from someone else, share it with u :)
------------------------------------------------------------------------------------
IMO the problem is in the AcceptSocket(). What the above program is doing is: It launches a new thread and then waits for a message. As soon as the first line of the HTTP request comes, it would read it, process it and then go back to the AcceptSocket. Thus whatever you send to the server after this is discarded untill you make another connection.
However if the browser is fast enough to send the complete request, you might receive the complete request.

You should make the following changes to make the above program work correctly:
//Constructor: There should be only one listener.
myListener = new TcpListener(port);
myListener.Start();

//Main Method
while(isRunnable)
{
Socket mySocket = myListener.AcceptSocket();

//start the thread which calls the method 'StartRead'
myThread = new ReaderThread();
myThread.mySocket = mySocket;
myThread.Start() ;
}

class ReaderThread : Thread
{
Socket mySocket;

//in the run or start method
if(mySocket.Connected)
{
//make a byte array and receive data from the client
Byte[] bReceive = new Byte[1024] ;

int i = mySocket.Receive(bReceive,bReceive.Length,0); //BUGS??
// rest of the code goes here


Take a look at http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemthreadingthreadstartclasstopic.asp to see an implementation in C#.
------------------------------------------------------------------------------------