The MASM Forum Archive 2004 to 2012

General Forums => The Workshop => Topic started by: Danesh on August 22, 2006, 12:40:48 AM

Title: Network problem
Post by: Danesh on August 22, 2006, 12:40:48 AM
Hi all,

I have a server and a client program and they will comminicate with each other on an open socket.
The server code is something like this:

.data
ReceivingBuffer   db   1000+1  dup(0)
Message1   db "Msg1", 0
Message2   db "Msg2", 0

.code
Invoke  recv, OpenedSocketHandleForThisClient, Addr ReceivingBuffer, 1000, 0
Invoke  send, OpenedSocketHandleForThisClient, Addr Message1, SizeOf Message1, 0      
Invoke  recv, OpenedSocketHandleForThisClient, Addr ReceivingBuffer, 1000, 0
Invoke  send, OpenedSocketHandleForThisClient, Addr Message2, SizeOf Message2, 0


and the client code is something like this:

invoke  send, S1, addr MyString, sizeof MyString, 0         
invoke  recv, S1, addr ReceivingBuffer, sizeof ReceivingBuffer, 0
invoke  send, S1, addr MyString, sizeof MyString, 0
invoke  recv, S1, addr ReceivingBuffer, sizeof ReceivingBuffer, 0

Print addr ReceivingBuffer

Now I expect that the client prints always "Message2" and it happens when I put 1 second delay between each loop that client sends and receives messages to and form the server. But when I run the client to send and receive messages countinously without any delay it will print sometimes (Message1) and sometimes (Message2). I don't know why this happens while I expect client and server to be synchronized by using this code! Can anybody help?

Besides when change the code as below:

Server:
Invoke  recv, OpenedSocketHandleForThisClient, Addr ReceivingBuffer, 1000, 0
Invoke  send, OpenedSocketHandleForThisClient, Addr Message1, SizeOf Message1, 0      
Invoke  send, OpenedSocketHandleForThisClient, Addr Message2, SizeOf Message2, 0

and client:
invoke  send, S1, addr MyString, sizeof MyString, 0         
invoke  recv, S1, addr ReceivingBuffer, sizeof ReceivingBuffer, 0
invoke  recv, S1, addr ReceivingBuffer, sizeof ReceivingBuffer, 0

in countinous sending, client program crashes. Can anybody help me to find a way to synchronize client and server tobe able to handle even incomming countinous messages from client?

Regards,

Danesh






Title: Re: Network problem
Post by: James Ladd on August 22, 2006, 03:15:33 AM
What does OpenedSocketHandleForThisClient do?
Can you show us the code?
Title: Re: Network problem
Post by: Tedd on August 22, 2006, 01:53:20 PM
James: OpenedSocketHandleForThisClient would be the socket handle :P


Danesh: You'll have to post a full app - this could come from any number of things, but what you've posted looks fine.
Title: Re: Network problem
Post by: P1 on August 22, 2006, 02:23:23 PM
Quote from: Danesh on August 22, 2006, 12:40:48 AMNow I expect that the client prints always "Message2" and it happens when I put 1 second delay between each loop that client sends and receives messages to and form the server. But when I run the client to send and receive messages countinously without any delay it will print sometimes (Message1) and sometimes (Message2). I don't know why this happens while I expect client and server to be synchronized by using this code! Can anybody help?
It's painfully obvious that you have a timing problem.  But have not included, what controls the tcp flow in this code snippet.  So there is no way of us helping your flow control.

Regards,  P1  :8)
Title: Re: Network problem
Post by: Danesh on August 22, 2006, 03:20:27 PM

James: Yes, OpenedSocketHandleForThisClient is socket handle returned by "accept" function.

Tedd: here is the code attached.

P1: Here is my code attached. Yes P1, as you said I have timing problem. In fact I don't know when the other side is ready to receive to send data to it and in other word I have problem to synchronize both sides of network. I hope to get good tips from you to solve it.

Regards,

Danesh



[attachment deleted by admin]
Title: Re: Network problem
Post by: Tedd on August 22, 2006, 05:22:45 PM
It is a little strange, yes, I get the same result. Each function SHOULD block until it finishes, and therefore the messages will be received in order (not to mention it's a tcp socket, so the messages should stay in order!)

Testing the server with my own client (though it does use async), I get the following behaviour:
client->server: "1"
server->client: "Message 1"
client->server: "1"
server->client: "Message 2"
(loop)

So the server appears to work as expected.


Yet, when using your client: at the end of each loop - yes I would expect it to print "Message 2", being the last message to be received - it prints "Message 1" quite often :dazzled:
Reducing the client's loop to only one send-receive causes mainly "Message 1" to be printed, but sometimes "Message 2" -- strrrrrrange! (We would hope it was 1 then 2, then 1 then 2 then.....)


The only thing that comes to mind is that it's a consequence of running all on the same machine, so the sockets are 'local' and there must be some kind of (winsock internal) thread concurrency/shortcut issue - where each recv writes to the buffer, but the last one to finish is the one to be printed.
I think simply running the client(s) and server on separate machines will fix it anyway. (Since the sockets aren't on the same machine, plus network latency.)
For testing, you might just have to stick to putting the delay in manually.


If that doesn't fix it, it might be worth re-doing it with async sockets (WSAAsyncSelect) and then you know when the message has fully been received (this may be the reason my client works.)
Title: Re: Network problem
Post by: P1 on August 22, 2006, 05:48:34 PM
Quote from: Tedd on August 22, 2006, 05:22:45 PMYet, when using your client: at the end of each loop - yes I would expect it to print "Message 2", being the last message to be received - it prints "Message 1" quite often :dazzled:
Reducing the client's loop to only one send-receive causes mainly "Message 1" to be printed, but sometimes "Message 2" -- strrrrrrange! (We would hope it was 1 then 2, then 1 then 2 then.....)
Buffers 101

He uses the same memory area without regard to reuse and/or clearing of messages.  So he has overlapping calls without the proper timing flow control to ensure orderly output.  IOW, sometimes you are printing "Message 1", just in time of the arival of "Message 2" without blocking until "Message 1" is printed.

Regards,  P1  :8)
Title: Re: Network problem
Post by: Tedd on August 22, 2006, 06:13:31 PM
Yes, but we're expecting that send and recv should block and not return until their operations have finished (i.e. the data has been sent/received).
But obviously this isn't quite what's happening.
Title: Re: Network problem
Post by: P1 on August 22, 2006, 06:13:52 PM
Quote from: Tedd on August 22, 2006, 05:22:45 PMIf that doesn't fix it, it might be worth re-doing it with async sockets (WSAAsyncSelect) and then you know when the message has fully been received (this may be the reason my client works.)
I would go that way myself as well.  Maybe a simple ack/nak for flow control for check.  A checksum for message corruption.

Regards,  P1  :8)
Title: Re: Network problem
Post by: P1 on August 22, 2006, 06:18:32 PM
Quote from: Tedd on August 22, 2006, 06:13:31 PMYes, but we're expecting that send and recv should block and not return until their operations have finished (i.e. the data has been sent/received).
Each stream is seperate.  Expect blocking, only when you setup for it.
QuoteValue   Meaning
SOCK_STREAM   Provides sequenced, reliable, two-way, connection-based byte streams with an out-of-band data transmission mechanism. Uses TCP for the Internet address family.

Sockets of type SOCK_STREAM are full-duplex byte streams. A stream socket must be in a connected state before any data can be sent or received on it. A connection to another socket is created with a connect call. Once connected, data can be transferred using send and recv calls. When a session has been completed, a closesocket must be performed. Out-of-band data can also be transmitted as described in send and received as described in recv.

What were you expecting on a streaming socket on an improperly used buffer?

Regards,  P1  :8)
Title: Re: Network problem
Post by: Tedd on August 22, 2006, 06:26:08 PM
tcp/ip already provides sequencing, ack, nack, checksum, flow control, windowing, ........ -- sockets of type SOCK_STREAM should provide this already.

How is the buffer improperely used? The send and recv functions are called sequentially, and they are (supposedly!) blocking - they should never attempt to access the buffer at the same time.
Title: Re: Network problem
Post by: P1 on August 22, 2006, 06:34:45 PM

... Server
TextMessage     DB  "Message 1", 0
OKMsg           db  "Message 2", 0
... Server
GetMsgFromClient: ; getting query loop

Invoke  recv, OpenedSocketHandleForThisClient, Addr ReceivingBuffer, 1000, 0

Invoke  send, OpenedSocketHandleForThisClient, Addr TextMessage, SizeOf TextMessage, 0

Invoke  recv, OpenedSocketHandleForThisClient, Addr ReceivingBuffer, 1000, 0

Invoke  send, OpenedSocketHandleForThisClient, Addr OKMsg, SizeOf OKMsg, 0

...   Client

    invoke  send, S1, addr QueryStr, sizeof QueryStr, 0         ; send the entered query to the server

    invoke  recv, S1, addr ReceivingBuffer, sizeof ReceivingBuffer, 0

    invoke  send, S1, addr QueryStr, sizeof QueryStr, 0         ; send the entered query to the server

    invoke  recv, S1, addr ReceivingBuffer, sizeof ReceivingBuffer, 0


To save some discussion here, please read what "SOCK_STREAM are full-duplex byte streams."  means.

Quote from: Tedd on August 22, 2006, 06:26:08 PMHow is the buffer improperely used?
Why would he program two different messages to the same buffer back to back?  Then expect the results to be different from the same buffer?

Regards,  P1  :8)
Title: Re: Network problem
Post by: Tedd on August 22, 2006, 06:44:57 PM
full-duplex means the stream is 'capable' of sending and receiving at the same time.

(blocking) send completes once the data has been passed up to the network, ready to be sent - the buffer is free to use again
(blocking) recv completes when the data from the message has been received - the buffer now contains the received message


He is receiving two messages, a then b (yes, both into the same buffer), and printing the contents of the buffer - expecting only b to be printed, as this is the last to be received. This is not an insane expectation.
If we receive 'a', then when that call returns the buffer should contain message a. If we then receive 'b', then once that call returns the buffer should contain message b. Printing the buffer at this point should print message b. Since the calls are 'blocking,' each recv should not return until its message has been fully received, so there should be no overlap between the two calls.
Title: Re: Network problem
Post by: Danesh on August 23, 2006, 01:27:39 PM
I am sure what Tedd is saying is right. When "recv" is called it wait until a message come from other side. Improper using of buffer is quite irrelevant while it will be updated after each receive. I think, however, "recv" will block the execution until it is done, but "send" will send the data as soon as it is ready so the problem would be timing between a send a receive. In other words, sometimes a send will be done before proper receive is ready to receive and this happens when there are more than one receive and send in code. I need to know, how can I be sure that the other side is ready to receive, to send the data to it? I thought maybe a delay after each send would give the other side enough time to be ready to go to receive state, but it would depend on network traffic, network speed, etc.

Regards,

Danesh
Title: Re: Network problem
Post by: P1 on August 23, 2006, 01:32:34 PM
Just let us know what works in the end.  And what you figured out from that.  That way we all can learn here.

Regards,  P1  :8)
Title: Re: Network problem
Post by: Tedd on August 23, 2006, 02:56:43 PM
I don't think you should need to wait for the (application at the) other side to be ready to receive (or send, when receiving.)
Messages are buffered at either side by winsock, so the other side can be considered always ready - if it's not then the call will fail anyway.

When "send" returns successfully, all this means is that winsock has buffered your message has made a start on sending it. TCP provides 'connections' and so when you do a send, winsock knows it's being received on the other side - so the send call returns successfully.
When "recv" returns successfully, it means the message has been copied from winsock's buffer into yours. The actual message may have already been there (waiting in winsock's buffers) 20 seconds before you even call recv. Or, it could be that there was no message immediately and so your call waits until there is one, and you receive that.

So you shouldn't have any problems with synching between server and clients, as this is handled invisibly already.

I think the problem in this case is that the sockets are running on the same local machine. As a result, send could complete (on the 'other' end) even before it returns successfully. The problem itself could be a mixed consequence of this kind of shortcut - which should only result when the two are both running on the same machine.
So, what you need to do is test it across two separate machines, and see if you can reproduce this strange effect at all. If not, then this is probably what's causing it, and you can assume your program is 'correct.' (Assuming it's meant for multiple machines.)
Title: Re: Network problem
Post by: Danesh on August 23, 2006, 11:15:04 PM
P1: Sure I will share with everybody if I could come to any solution.

Tedd: I tested server and client programs on seprate machines and as I expected the problem still exists. In my tests, I ran the server on my notebook and client from my system. When I press enter (on client side) and hold it (it sends data countinously) it strats to get "Message 1" from server which seems to be good but after few seconds it send "Message 2" and then after few seconds "Message 1" and so on.

D.
Title: Re: Network problem
Post by: Tedd on August 24, 2006, 12:50:05 PM
Forget this headache :bdg
Learn how to use WSAAsyncSelect. The you can receive a message when the data has been received, which should avoid this problem.
Title: Re: Network problem
Post by: P1 on August 24, 2006, 02:13:34 PM
Quote from: Tedd on August 24, 2006, 12:50:05 PMLearn how to use WSAAsyncSelect. The you can receive a message when the data has been received, which should avoid this problem.
Exactly !!!   :U

I was checking up on SOCK_STREAM from a M$ source and it's not pretty.  Reminds me of the old serial stuff that I had done.

Regards,  P1  :8)
Title: Re: Network problem
Post by: Danesh on August 24, 2006, 11:40:37 PM
Sure. I will try WSAAsyncSelect.

Thanks P1 and Tedd. You showed me the way.