Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

CAsyncSocket/CWinThread/Service

209 views
Skip to first unread message

synx

unread,
Apr 14, 2006, 7:30:56 AM4/14/06
to

im developing a udp based client/service app that happens to be windows
service apps.

*serverService* : a service that sends/recv the data to/from client.
i used WaitforSingleObject as a timer for serverService in a while(1)
loop, that signals the event and serverService sends data to the
clientService. the loop starts whenever the ServiceMain() is called
from the SCM.

clientservice: a service that sends/recv data from server
similarly, i used WaitForSingleObject as a timer for my clientservice
app, which sends the data to serverService very well.

but fortunately, both the services are unable to receive anything. even
the OnReceive() Event is not getting triggered.

while i run the exact code using a Dialog-based app, both
apps(client/server) runs fine and to the desired expectations.

Findings:
Therefore, just recognized after a fairly fine debugging that the
neither serverService nor clientService was receiving any thing from
each other, altho both services are sending the data.

it seems that, because both the services are in while loop therefore
they can only do the tasks called from within the while loop.

Workaround:
so i guess i wud have to start another while(1) loop for both the
services... that shud check and read the port for any prospective
incoming message.

Results:
well, i did the above mentioned workaround, like while(1)
ReceiveFrom(...), but once again, fortunately, it did not work.

*Conclusion*:
CAsyncSocket requires a message pump. Any ideas where shud i put my
message_pump, the loop, so that i may get the exact message for the
OnReceive to be called. Any snippets, links, articles?

Anybody has used the sockets in service??? Send() is S_OK, but How to
Receive()??

Any ideas for the simple problem?


Best regards,
JT!

--
synx
------------------------------------------------------------------------
Posted via http://www.codecomments.com
------------------------------------------------------------------------

Scott McPhillips [MVP]

unread,
Apr 14, 2006, 11:06:51 AM4/14/06
to
synx wrote:
> CAsyncSocket requires a message pump. Any ideas where shud i put my
> message_pump, the loop, so that i may get the exact message for the
> OnReceive to be called. Any snippets, links, articles?

The message pump that CAsyncSocket requires is built into CWinThread.
Create a user-interface type of CWinThread and create the socket(s) in
that thread. Do not use a while(1) loop. Instead, return from the
thread's InitInstance to the message pump. Then OnReceive will be
called when data arrives.

--
Scott McPhillips [VC++ MVP]

Joseph M. Newcomer

unread,
Apr 14, 2006, 10:48:25 PM4/14/06
to
See below...

On Fri, 14 Apr 2006 06:30:56 -0500, synx <synx....@mail.codecomments.com> wrote:

>
>im developing a udp based client/service app that happens to be windows
>service apps.
>
>*serverService* : a service that sends/recv the data to/from client.
>i used WaitforSingleObject as a timer for serverService in a while(1)
>loop, that signals the event and serverService sends data to the
>clientService. the loop starts whenever the ServiceMain() is called
>from the SCM.

****
The whole concept of using WaitForSingleObject as a timer is scary. And generally,
ServiceMain should just block on a termination event, and launch a thread to do the actual
service work.
****


>
>clientservice: a service that sends/recv data from server
>similarly, i used WaitForSingleObject as a timer for my clientservice
>app, which sends the data to serverService very well.
>
>but fortunately, both the services are unable to receive anything. even
>the OnReceive() Event is not getting triggered.
>
>while i run the exact code using a Dialog-based app, both
>apps(client/server) runs fine and to the desired expectations.
>
>Findings:
>Therefore, just recognized after a fairly fine debugging that the
>neither serverService nor clientService was receiving any thing from
>each other, altho both services are sending the data.
>
>it seems that, because both the services are in while loop therefore
>they can only do the tasks called from within the while loop.
>
>Workaround:
>so i guess i wud have to start another while(1) loop for both the
>services... that shud check and read the port for any prospective
>incoming message.

****
This seems a bit weird. Why would have have to check a port? That's what asynchronous
network notifications are for!
****


>
>Results:
>well, i did the above mentioned workaround, like while(1)
>ReceiveFrom(...), but once again, fortunately, it did not work.
>
>*Conclusion*:
>CAsyncSocket requires a message pump. Any ideas where shud i put my
>message_pump, the loop, so that i may get the exact message for the
>OnReceive to be called. Any snippets, links, articles?

****
Writing services in MFC is always a bit risky. But if you are using CAsyncSocket, the
while loop and WaitForSingleObject pretty much explain why you aren't getting anything.
These are both completely inappropriate for CAsyncSocket. You should be starting UI
threads to handle this, and the threads should not contain any kind of blocking or looping
construct that blocks the message pump.
****


>
>Anybody has used the sockets in service??? Send() is S_OK, but How to
>Receive()??
>
>Any ideas for the simple problem?
>
>
>Best regards,
>JT!

Joseph M. Newcomer [MVP]
email: newc...@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
--
NewsGuy.Com 30Gb $9.95 Carry Forward and On Demand Bandwidth

synx

unread,
Apr 17, 2006, 8:29:47 AM4/17/06
to

0) All communication is UDP based using multicast.
1) I have this class call CServerSocket derived from CAsyncSocket.
2a) Another class CThreadSock derived from CWinThread.
2b) All of the socket connection/Tx/Rx/etc work is done in
CServerSocket.
3) ServiceMain() i hve done like:

Code:
--------------------
CThreadSock* m_pThread =(CThreadSock*) AfxBeginThread(RUNTIME_CLASS(CThreadSock),THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED);
if (m_pThread)
m_pThread->ResumeThread();
--------------------


CThreadSock.h
Code:
--------------------

CServerSocket m_Server;
--------------------

Code:
--------------------

CThreadSock::InitInstance()
{
m_Server.StartServer();//this call just creates a socket and returns.
}
--------------------

now how do i tell the CThreadSock that it shud now receive
WM_SOCKET_NOTIFY message.
what "else" do i need to do so that the OnReceive in CServerSocket gets
called automatically??

Scott McPhillips [MVP]

unread,
Apr 17, 2006, 11:02:36 AM4/17/06
to
synx wrote:
> now how do i tell the CThreadSock that it shud now receive
> WM_SOCKET_NOTIFY message.
> what "else" do i need to do so that the OnReceive in CServerSocket gets
> called automatically??

You don't have to do anything else to make the message handling work:
CAsyncSocket and CWinThread are designed to work together.

Other:
You must return TRUE from InitInstance.
If you are expecting to receive UDP broadcasts you must enable the
broadcast option after you create the socket:
int Option = 1;
SetSockOpt(SO_BROADCAST, &Option, sizeof(Option));

Joseph M. Newcomer

unread,
Apr 17, 2006, 1:47:58 PM4/17/06
to
Actually, the question said multicast, which is actually a lot more complicated.

Also, key here is that the socket either must be created in the CWinThread class, or
handed across via Detach/Attach (as per my essay on UI threads on my MVP Tips site).
joe

On Mon, 17 Apr 2006 11:02:36 -0400, "Scott McPhillips [MVP]" <org-dot-mvps-at-scottmcp>
wrote:

synx

unread,
Apr 17, 2006, 10:44:33 PM4/17/06
to

Thank you scott and joe for your time (o:

> Scott McPhillips [MVP]: You don't have to do anything else to make the


> message handling work:CAsyncSocket and CWinThread are designed to work
> together.

This infers that the OnReceive in CServerSocket is able to get called
as soon as it receives the data?

> Other:
> You must return TRUE from InitInstance.

I suppose InitInstance() by default returns TRUE, atleast in my case i
didnt have to change.

> If you are expecting to receive UDP broadcasts you must enable the
> broadcast option after you create the socket:
> int Option = 1;
> SetSockOpt(SO_BROADCAST, &Option, sizeof(Option));

UDP multicast option is working absolutely perfect, therefore it doesnt
need any concern, i think.

_PLUS,_THE_CORE_OF_THIS_POST_IS_THE_FOLLOWING_QUESTION:_[/B]
*WHAT DO I DO TO TELL CTHREADSOCK THAT IT SHUD NOW BE PASSING MESSAGES
TO CSERVERSOCKET?

The previous post mentioned what has been done uptill now, and so far
[b]no* good has happen, means that it isint receiving any messages.

JOSEPH M. NEWCOMER


> Actually, the question said multicast, which is actually a lot more
> complicated.

Thank you joe, i had a great time learning settings and using the
multicast option, but i didnt find it hard. May be thts because im now
too much familiar with it? (o:

>
> Also, key here is that the socket either must be created in the
> CWinThread class, or handed across via Detach/Attach (as per my essay
> on UI threads on my MVP Tips site).

dont you think that while im doing the following, is the correct way?

CThreadSock.h (declaration of CServerSocket member in CThreadSock

Code:
--------------------
CServerSocket m_Server;
--------------------

Code:
--------------------
CThreadSock::InitInstance()
{
m_Server.StartServer();//this call just creates a socket and returns.
}
--------------------

also i fogot to mention, just for the information, that StartServer()
also enables the multicasting option. Which is working fine, having run
and tested in a dialog based app.

but what is *not working fine* is that CServerSocket in unable to
receive any messages/data, despite the fact that i have used a UI
Thread to start a message pump.

Any snippets, code, links, watever that could solve this little
problem.

Thank you,

Scott McPhillips [MVP]

unread,
Apr 18, 2006, 8:28:08 AM4/18/06
to
synx wrote:
> Thank you scott and joe for your time (o:
>
>
>>Scott McPhillips [MVP]: You don't have to do anything else to make the
>>message handling work:CAsyncSocket and CWinThread are designed to work
>>together.
>
> This infers that the OnReceive in CServerSocket is able to get called
> as soon as it receives the data?


Yes, if the thread's message pump is running.

>
>
>>Other:
>>You must return TRUE from InitInstance.
>
> I suppose InitInstance() by default returns TRUE, atleast in my case i
> didnt have to change.


I don't understand this. It should not even compile if you are not
returning a value. You MUST return TRUE for the thread's message pump
to run. Is InitInstance executing? Why do you think you "didn't have
to change?"


> _PLUS,_THE_CORE_OF_THIS_POST_IS_THE_FOLLOWING_QUESTION:_[/B]
> *WHAT DO I DO TO TELL CTHREADSOCK THAT IT SHUD NOW BE PASSING MESSAGES
> TO CSERVERSOCKET?
>
> The previous post mentioned what has been done uptill now, and so far
> [b]no* good has happen, means that it isint receiving any messages.


You do not have to do anything to tell the thread to dispatch the
message to the socket, except make sure that the thread's message pump
is running.


> also i fogot to mention, just for the information, that StartServer()
> also enables the multicasting option. Which is working fine, having run
> and tested in a dialog based app.
>
> but what is *not working fine* is that CServerSocket in unable to
> receive any messages/data, despite the fact that i have used a UI
> Thread to start a message pump.
>
> Any snippets, code, links, watever that could solve this little
> problem.

Your dialog based app is a fine example. The only difference when
running in a separate thread is that the thread's message pump must be
running. Is yours? The thread's message pump is in the CWinThread::Run
fuction. After a network message has been sent, break into your program
and see if your thread is running this function.

Joseph M. Newcomer

unread,
Apr 18, 2006, 11:12:28 AM4/18/06
to
It will get called. "As soon as" is problematic, because there are overheads and issues
like the scheduler (just because a thread *can* run doesn't mean it *will* run "right
now")

I don't know what you mean by the question. One socket cannot pass messages to another,
so there is no issue about how one socket can pass messages to another. But in MFC terms,
if you get a socket in one thread, and want to transfer control of that CAsyncSocket to
another thread, you have to do a "hand off": you Detach the SOCKET object from the
CAsyncSocket in the creating thread and Attach it to a CAsyncSocket in the thread that is
going to use it. The SOCKET object is the same; but MFC uses per-thread socket maps to
map SOCKET objects to MFC CAsyncSocket objects, and that's what you have to deal with.

My essay on UI threads on my MVP Tips site shows one way to do this; however, any code
that accomplishes the same transfer will work. In some cases I do a PostThreadMessage
from the one thread to the other, e.g.,
networkThread->PostThreadMessage(UWM_NEW_SOCKET,
(WPARAM)socket.Detach());
and the receiver does
void CNetworkThread::OnNewSocket(WPARAM wParam, LPARAM)
{
SOCKET s = (SOCKET)wParam;
CMySocketHandler * handler = new CMySocketHandler;
handler->Attach(s);
}

(Obviously, this is the bare-bones of the code, since it omits error checking, and any
other setup and initialization that might be required, for example, keeping track of the
instances of CMySocketHandler in case I would care)
joe

kamr...@gmail.com

unread,
Apr 19, 2006, 3:39:35 AM4/19/06
to
i was unable to post a followup from codecomments, therefore im
relpying from here. i wonder the code-tags wud work?

[quote]> Scott McPhillips [VC++ MVP]
> This infers that the OnReceive in CServerSocket is able to get called as soon as it receives the data? Yes, if the thread's message pump is running.[/quote]
Yes, the thread's message pump is running.

[quote]> I don't understand this. It should not even compile if you
are not returning a value. [/quote]
True, because it has a BOOL return-TYPE, and atleast i'd have to return
something for my program to be compilied.

[quote]> You MUST return TRUE for the thread's message pump to run.
[/quote]
Yes, thts correct. And if i return-FALSE, the message pump will not
start, i.e Run() will not be called, correct?

[quote]> Is InitInstance executing? [/quote]
Yes, InitInstance() is executing, as i do the AfxBeginThread() from
ServiceMain() method.

[quote]> Why do you think you "didn't have to change?"[/quote]
I added a class CThreadSock derived from CWinThread using ClassWizard,
therefore the ClassWizard added the CThreadSock IN my project with all
the necessary code having TODOs. Also, IN InitInstance() it(the
classwizard) sets the return-TYPE to TRUE. So thts why i said i did not
have to change the 'return-type' from false to true, as it was already
returning TRUE. I hope you understand what i just explained? It was not
very important, but i mentioned it to be clear on both sides.

[quote]> You do not have to do anything to tell the thread to dispatch


the
> message to the socket, except make sure that the thread's message pump

> is running.[/quote]
Well, im hundred-one percent sure, that thread's message pump is
running.

[quote]Joe:>But in MFC terms, if you get a socket in one thread, and


want to transfer control of that CAsyncSocket to another thread, you
have to do a "hand off": you Detach the SOCKET object from the
CAsyncSocket in the creating thread and Attach it to a CAsyncSocket in
the thread that is going to use it. The SOCKET object is the same; but
MFC uses per-thread socket maps to map SOCKET objects to MFC

CAsyncSocket objects, and that's what you have to deal with.[/quote]
Is it "really-really" necessary, I mean do i really-have-to you Detach
the SOCKET object from CServerSocket in the creating thread and Attach
it to a CServerSocket in the thread(CThreadSock) that is going to use
it?

What if i need to create the socket IN the CThreadSock thread? The
ServerApp does not do the [b]<accept>[/b] thing. It only creates a
port, and start tx/rx the data. Virtually its just an app, with an open
port doing tx/rx. and similar is the ClientApp. May be i shud have
cleared this fact earlier?

The solution you just mentioned seems for if a client connects to the
Server, then Server shud create a socket for tht client, detach the
socket, spawn a thread, and attach the socket in the thread. Here i
only need to create a port, and do Tx/Rx. What do you think about this?

At the moment, im doing the following:
[code][color=blue]BOOL CThreadSock::InitInstance()
{
StartServer();//local method
return TRUE;
}[/color]

//the code in the StartServer method
[color=blue]CThreadSock::StartServer()
{
//CServerSocket* m_pSocket, declared in ThreadSock.h
m_pSocket = new CServerSocket();
if(SOCKET_ERROR == m_pSocket->Create(PTP_EVENT_PORT,SOCK_DGRAM))
{
return failure;
}
else
{
m_pSocket->InitMulticastDest();//method in CServerSocket, initializes
m_addrMulti
}

[color=teal]//With the following lines commented, the app starts, the
message-pump starts,
//but it doesnt receive anything at all.
/****
CString str = _T("test1239");
if(SOCKET_ERROR == m_pSocket->SendTo(str,str.GetLength(),
(struct sockaddr*) &m_pSocket->m_addrMulti,
(sizeof(m_pSocket->m_addrMulti)))
)
{
return failure;
}
****/[/teal]
}[/color][/code]

[b]Strange:[/b]
1. if i remove(uncomment) the above comments the behavior is some-what
changed.

[b]for example:[/b]
1) when i start, first this(ServerApp) app, and then Client App.
Nothing happens.
2) when i start, first the Client app, and then ServerApp. The
ServerApp starts receiving the data from the ClientApp, and on
receiving it even sends the data to the ClientApp. Which is what i
want.

[b]FYI:[/b] Keeping the fact in view that ServerApp is a Windows
Service which i start thru Microsoft Management Console(or SCM, watever
you call it)

well, i tested(with-comments-removed) the following with four
possibilities:

1) firstStart-ServerApp-then-ClientApp
2) firstStart-ServerApp-then-ClientApp-then-restartServer
3) firstStart-ClientApp-then-ServerApp
4) firstStart-ClientApp-then-ServerApp-then-restartClientApp

[b]Test#1:[/b]
1) ServerApp started, and then ClientApp. Nothing happens.

[b]Test#2:[/b]
1) ServerApp started, and then ClientApp. Nothing happens. But with
ClientApp running, the ServerApp is RESTARTED(from SCM). The ServerApp
starts receiving the data.

[b]Test#3:[/b]
1) ClientApp started, and then ServerApp. ServerApp starts receiving
the data.

[b]Test#4:[/b]
1) ClientApp started, and then ServerApp. ServerApp starts receiving
the data. Now, With ServerApp running, the ClientApp is closed, and
then started again, Nothing happens. ServerApp stops receiving the
data.

[b][u]But is not it strange? [/u][/b]
from the code above, im getting an idea that, for my ServerApp to work
correctly, i wud first need To start the ClientApp, and then the
ServerApp.
and you can see that as soon as the ServerApp starts, it sends some
data(test1239) to the ClientApp. If ClientApp receives that data from
ServerApp, ONLY-THEN the ServerApp begins receiving the data. Otherwise
it does not do so.

if i do not remove the comments, the ServerApp doesnt receive anything.
if i do uncomment, i wud first need to start my ClientApp, and then the
ServerApp.

[b]why? what the _stupid_hell_ im doing wrong???¿[/b] I wanted my app
to be asynchronous IN nature.

ServerApp, a UDP based Server, does not maintain a list of its Clients.
ServerApp just multicast the messages To a specific port/address.
Each client when started, joins to that multicast GROUP, and begin the
Tx/Rx.

So, technically, both apps server/client, do not do the
<connect/accept> thing. They(server/client) only creates a port, and
start tx/rx the data.

This UDP based Server/ClientApp has been run and tested in a
dialog-based app.
At the moment, the Server is a Windows Server app. And client is a
dialog-based ClientApp.

Well, thts too much of a question.
I thank both of you, and your precious time, you really deserve to be
MS_MVP.

synx

unread,
Apr 20, 2006, 2:31:14 AM4/20/06
to

you guys there?

Joseph M. Newcomer

unread,
Apr 21, 2006, 1:14:08 AM4/21/06
to
See below...

On 19 Apr 2006 00:39:35 -0700, kamr...@gmail.com wrote:

>i was unable to post a followup from codecomments, therefore im
>relpying from here. i wonder the code-tags wud work?
>
>[quote]> Scott McPhillips [VC++ MVP]
>> This infers that the OnReceive in CServerSocket is able to get called as soon as it receives the data? Yes, if the thread's message pump is running.[/quote]
>Yes, the thread's message pump is running.

****
Which means that a message will be queued up for later processing, as soon as the thread
can be scheduled, which is some time in the indefinite future relative to when the data is
actually received.
****


>
>[quote]> I don't understand this. It should not even compile if you
>are not returning a value. [/quote]
>True, because it has a BOOL return-TYPE, and atleast i'd have to return
>something for my program to be compilied.
>
>[quote]> You MUST return TRUE for the thread's message pump to run.
>[/quote]
>Yes, thts correct. And if i return-FALSE, the message pump will not
>start, i.e Run() will not be called, correct?

****
If you return FALSE from InitInstance, there is no attempt to call Run(), which invokes
the message pump. You can see this from reading the MFC source code.
****


>
>[quote]> Is InitInstance executing? [/quote]
>Yes, InitInstance() is executing, as i do the AfxBeginThread() from
>ServiceMain() method.

****
Ideally there should be no problem here...
****


>
>[quote]> Why do you think you "didn't have to change?"[/quote]
>I added a class CThreadSock derived from CWinThread using ClassWizard,
>therefore the ClassWizard added the CThreadSock IN my project with all
>the necessary code having TODOs. Also, IN InitInstance() it(the
>classwizard) sets the return-TYPE to TRUE. So thts why i said i did not
>have to change the 'return-type' from false to true, as it was already
>returning TRUE. I hope you understand what i just explained? It was not
>very important, but i mentioned it to be clear on both sides.

****
OK, that wasn't clear from the original post. Yes, the skeleton returns TRUE when it is
first created
****


>
>[quote]> You do not have to do anything to tell the thread to dispatch
>the
>> message to the socket, except make sure that the thread's message pump
>> is running.[/quote]
>Well, im hundred-one percent sure, that thread's message pump is
>running.

****
Note that the socket must be owned by the thread, in the sense of the MFC handle map. That
is, the thread which is going to dispatch the messages must have the SOCKET mapped to your
CAsyncSocket-derived class in that thread, and that thread only
****


>
>[quote]Joe:>But in MFC terms, if you get a socket in one thread, and
>want to transfer control of that CAsyncSocket to another thread, you
>have to do a "hand off": you Detach the SOCKET object from the
>CAsyncSocket in the creating thread and Attach it to a CAsyncSocket in
>the thread that is going to use it. The SOCKET object is the same; but
>MFC uses per-thread socket maps to map SOCKET objects to MFC
>CAsyncSocket objects, and that's what you have to deal with.[/quote]
>Is it "really-really" necessary, I mean do i really-have-to you Detach
>the SOCKET object from CServerSocket in the creating thread and Attach
>it to a CServerSocket in the thread(CThreadSock) that is going to use
>it?

*****
It is absolutely, positively, non-negotiably necessary. You really, absolutely,
positively, beyond any shadow of a doubt (no possible doubt whatever) detach the SOCKET
object in its original thread and Attach() it in the thread that is going to handle the
connection.
*****


>
>What if i need to create the socket IN the CThreadSock thread? The
>ServerApp does not do the [b]<accept>[/b] thing. It only creates a
>port, and start tx/rx the data. Virtually its just an app, with an open
>port doing tx/rx. and similar is the ClientApp. May be i shud have
>cleared this fact earlier?

****
In that case, there would be no problem, because the socket would already be in the
thread's handle map. You only need to Detach/Attach if the MFC socket object and the
underlying SOCKET are created in one thread, but a completely different thread is going to
manage the data flow
***


>
>The solution you just mentioned seems for if a client connects to the
>Server, then Server shud create a socket for tht client, detach the
>socket, spawn a thread, and attach the socket in the thread. Here i
>only need to create a port, and do Tx/Rx. What do you think about this?

****
The Accept call does this: the server creates a whole brand-new SOCKET for the connection,
then the CAsyncSocket::Accept method binds that SOCKET to the CAsyncSocket& object passed
into Accept. That object is now in the handle map. Note that once this is done, you will
have to make sure that no other Accept mentions the same CAsyncSocket object, e.g.,
while(TRUE)
{
CMyServerSocket sock;
listenerSocket.Accept(sock);
// ... stuff here
}

cannot work correctly. If you do an iterative server, that is, if the entire transaction
is handled in the "stuff here" code (during which you cannot accept any other concurrent
incoming connections) and you sock.Close() before the loop executes, you're fine. But if
you need to handle many connections, either fully asynchronously or via a thread, you
should probably do
while(TRUE)
{
CMyServerSocket * sock = new CMyServerSocket;
listernerSocket.Accept(*sock);
// ...stuff here
}
then you can have correct behavior, because, now all input will be directed to the correct
instance of CMyServerSocket. Or you can do
while(TRUE)
{
CMyServerSocket sock;
listenerSocket.Accept(sock);
CMySocketThread * handler =
(CMySocketThread *)AfxBeginThread(RUNTIME_CLASS(...),
CREATE_SUSPENDED);
handler->sock = sock.Detach();
handler->ResumeThread();
}

BOOL CMySocketThread::OnInitInstance()
{
serversocket.Attach(sock); // CMyServerSock serversocket;
return TRUE;
}

This is the simplest and most straightforward approach which has one thread per
connection. If you want lots of connections, this would not be a good approach; instead,
you might have a single thread handling lots of CAsyncSockets,
****

***
Note that this could return a failure and GetLastError() would return WSA_EWOULDBLOCK,
which would be legitimate, it would merely indicate the data can't be sent yet. Then you
would get an OnSend callback during which you would send the data.

Also remember that a UDP packet has a maximum length of 536 bytes, including the header,
which means a typical payload of 512 bytes, so you can't send anything larger.
****


>[b]Strange:[/b]
>1. if i remove(uncomment) the above comments the behavior is some-what
>changed.
>
>[b]for example:[/b]
>1) when i start, first this(ServerApp) app, and then Client App.
>Nothing happens.
>2) when i start, first the Client app, and then ServerApp. The
>ServerApp starts receiving the data from the ClientApp, and on
>receiving it even sends the data to the ClientApp. Which is what i
>want.

****
I'm late and it's sleepy, or something like that, so I'm not going to try to answer this
because I'd have to understand it. Sorry, it's been a very long day, started at 6:30 am
and it is now 1a.m. But beware of the SendTo failing because it is quite possible it is
*supposed* to fail...
****

****
This is UDP. You will never know, nor can you ever find out, if the client app has
received your SendTo, unless you impose a complex timeout mechanism on top of your
protocol. So requiring that the client app receive it is problematic. Even if you send
it successfully, the client machine is free to throw it away! Or it might never see it!
So you cannot rely on any form of triggering like this to do anything useful, unless you
have something like a SetTimer sequence that sends one of these "please start sending me
data" messages every so often (100ms? 10s? your problem domain, you need to figure it out.
And you need to have client apps that have already received the notice accept additional
redundant notifications).
****
>
>[b]why? what the _stupid_hell_ im doing wrong???ż[/b] I wanted my app


>to be asynchronous IN nature.
>
>ServerApp, a UDP based Server, does not maintain a list of its Clients.
>ServerApp just multicast the messages To a specific port/address.
>Each client when started, joins to that multicast GROUP, and begin the
>Tx/Rx.

****
Note that if a client sends a message to your server, (a) it may not get out, and you will
get no error report (b) it may get out and not get delivered, and you will get no error
report (c) it may get out and get delivered, but be thrown away by the receiving machine
after it is received, and you will get no error report (d) the receiving machine may get
two or more copies of the message (e) three messages send out ABC may arrive, if they
arrive at all, in any permuation, such as CBA, CAB, ABC, ACB, BCA, BAC, and on top of
these permuations, duplication (d) and lossage (a)(b)(c) can additionally occur. It is
your responsiblity to put enough information in the message, such as packet numbers and
packet types, to allow the recipient to sort this whole mess out.

Doing error recovery in UDP, especially in multicast, can be very difficult. But you
cannot assume that *any* message, once Send/SendTo has returned, has done anything at all.
It is an *unreliable* protocol, with all that implies. Furthermore, you cannot assume
that data you send has been received, or that you will receive a notification of a new
client arriving, or leaving, or anything else. On a good day, with the moon in full
phase, and with Mars in triune with Jupiter, and if the number of 100us ticks since Jan 1,
1600 is a prime number, packets may be lost. Or perhaps packets may be not-lost. It's an
unpredictable situation, and there's nothing you can do about it except to assume that the
protocol isn't going to work reliablly (e.g., you can't send a frame and 200 frame deltas;
they may not even arrive in FIFO order relative to how they were sent. Instead, like
MPEG, you send a full chunk of data, then a small number of deltas, then another full
chunk. You must provide everything required to detect if the deltas are associated with
the previous full chunk (typically this is a problem of multicast video, by the way)
****


>
>So, technically, both apps server/client, do not do the
><connect/accept> thing. They(server/client) only creates a port, and
>start tx/rx the data.
>
>This UDP based Server/ClientApp has been run and tested in a
>dialog-based app.

****
Well, it may have been run, but if you have not forced packet lossage, packet duplication,
and packet reordering, and all possible combinations of these across a variety of
sequences of packets, then it hasn't actually been tested,
****


>At the moment, the Server is a Windows Server app. And client is a
>dialog-based ClientApp.
>
>Well, thts too much of a question.
>I thank both of you, and your precious time, you really deserve to be
>MS_MVP.

synx

unread,
Apr 20, 2006, 11:37:38 PM4/20/06
to

man...! i really needed this help!!!
0 new messages