News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Network problem

Started by Danesh, August 22, 2006, 12:40:48 AM

Previous topic - Next topic

Danesh

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







James Ladd

What does OpenedSocketHandleForThisClient do?
Can you show us the code?

Tedd

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.
No snowflake in an avalanche feels responsible.

P1

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)

Danesh


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]

Tedd

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.)
No snowflake in an avalanche feels responsible.

P1

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)

Tedd

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.
No snowflake in an avalanche feels responsible.

P1

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)

P1

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)

Tedd

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.
No snowflake in an avalanche feels responsible.

P1


... 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)

Tedd

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.
No snowflake in an avalanche feels responsible.

Danesh

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

P1

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)