CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 14 of 14
  1. #1
    Join Date
    Jul 2001
    Location
    Trutnov, Czech Republic
    Posts
    459

    To replace CAsyncSockets with WinSock, THAT's the question...

    Hi,
    I've large project (FTP Server) which is based on CAsyncSockets. Unfortunately, sometimes while high utilization, it doesn't manage it (eg. it hangs up in CAsyncSocket::Receive()).

    And here comes the question: I'm interested in the fact, whether it would help to replace MFC Sockets with WinSock sockets (I mean WSAXxx() functions). Would the result be worth the effort to replace it?

    You see, it's not easy to force myself to do such a big change in this project, which is otherwise completed.

    Please write any opinion you have, I just need to decide...

    Thank you in advance, Standa.

  2. #2
    Join Date
    Jan 2002
    Location
    Scaro, UK
    Posts
    5,940
    Actually it won't be such a big change. You can implement your own version of CAsyncSocket with the same interface (i.e. same member functions & overrides) using Winsock. Then you'll have total control over how it works.

    I'd have a class CAsyncSocket2 which is derived from CWnd, which on connection calls ::connect etc and creates a hidden window for itself. Then use ::WSAAsyncSelect to process messages and pass them to your own OnReceive/OnClose etc virtual functions.

    Not too difficult I would say.

    I might add I've already done this, only my stuff fires up a seperate thread to handle incoming messages using WSAEventSelect (the reason for this is because the threads are part of a pool to do receives so one machine can cope with thousands of concurrent connections without having to have thousands of windows). I also have seperate threads to do the send too just in case of blocks/can't send because receiving messages (again part of a thread pool).

    Anyway for your case just using windows should be fine if you're wanting <50 connections per server.

    So in conclusion, just implement all the same functions as in CAsyncSocket (i.e. Create, Send, OnReceive, OnClose etc) in your own class but use winsock instead.

    Darwen.

  3. #3
    Join Date
    Jan 2002
    Location
    Scaro, UK
    Posts
    5,940
    Oh, just an additional....

    Using CAsyncSelect and CWnd to process your messages you should be fine up to around 300 connections (I said 50 connections in haste). But you must bear in mind if it's single threaded it will suffer from a linear degredation of speed with every connection.

    I had a similar situation on a 2.4GHz machine (nothing special) with 256Mb RAM and ran 300 connections without any problems on it apart from slowdown (obviously). It wasn't too bad though.
    Pretty good all things considered, but every operation was pretty quick (i.e. I'd open files, and then just read from them and post the data in chunks of 64k).

    But I needed to be able to cope with thousands of connections which is why I used multi threading to speed it all up.

    Good luck !

    Darwen.

  4. #4
    Join Date
    Jan 2002
    Location
    Scaro, UK
    Posts
    5,940
    Sorry, second line should have read "using AsynSelect" not "CAsyncSelect" - typo. I ought to read my posting before sending them.

    My apologies for any confusion.

    Darwen.

  5. #5
    Join Date
    Jan 2002
    Location
    Scaro, UK
    Posts
    5,940
    Ha ha ! Did it again ! AsyncSelect. I forgot the 'C'.

    Lol, lol, lolly lollypops !

    Darwen.

  6. #6
    Join Date
    Jul 2001
    Location
    Trutnov, Czech Republic
    Posts
    459
    Originally posted by darwen
    I'd have a class CAsyncSocket2 which is derived from CWnd, which on connection calls ::connect etc and creates a hidden window for itself. Then use ::WSAAsyncSelect to process messages and pass them to your own OnReceive/OnClose etc virtual functions.
    Creating hidden notification window is just something I would like to get rid of - that's the way MFC Sockets work. But I hope WinSock uses some more intelligent way, doesn't it?

    Maybe I didn't emphasize it adequately, but I also want to know, whether problems I currently have (eg. being frozen up in CAsyncSocket::Receive()) COULD be solved with using WinSock instead...

  7. #7
    Join Date
    Jan 2002
    Location
    Scaro, UK
    Posts
    5,940
    You can use WSAEventSelect etc in winsock to do event notification through events, and then you don't need windows.

    However you will need threads to constantly wait for messages and then pass them back to your main thread.

    Darwen.

  8. #8
    Join Date
    Jan 2002
    Location
    Scaro, UK
    Posts
    5,940
    And yes it will solve your blocking problems as you have complete control over the operation of the socket - which you don't have with CAsyncSocket.

    Darwen.

  9. #9
    Join Date
    Jul 2003
    Location
    Korea
    Posts
    60

    Angry

    By the way, I have a problem. I use MFC Socket class: CAsynSocket. I want to check connection status with the lowest cost.

    - Whenever call connect, return value will reveal connection status.
    - Whenever WM_CLOSE is notified, connection status is updated.

    But my problem is that CAsynSocket::Connect always return WSAEWOULDBLOCK even server exists or do not.

    So my solution is that I derived CAsyncSocket::Connect where I call Connect twice continuously. The last return value will be the desired value. It works well in WinXP. In Win2000, or Win98, some time my Connect() implementation raise error.

    Anyone has a idea? Thanks. Here is my snippet code:

    m_bConnect = CAsyncSelect::Connect( m_strServerIP, m_nServerPort);
    m_bConnect = CAsyncSelect::Connect( m_strServerIP, m_nServerPort);
    DWORD dwError = GetLastError();
    if( m_bConnect || (dwError == WSAEISCONN) )
    {
    m_bConnect = TRUE;
    return TRUE;
    }else
    {
    m_bConnect = FALSE;
    }
    Quang

  10. #10
    Join Date
    Jan 2002
    Location
    Scaro, UK
    Posts
    5,940
    I presume your code is disconnecting & shutting down the socket appropriately on the second call to connect ?

    WSAWOULDBLOCK is returned as WSALastError if - guess what - the socket is doing something and the function call would force winsock to wait for it to finish before continuing.

    I usually get around this by using a select statement with a non-infinite timeout to wait for rediness to read and write. Not too sure how to do this with a connect though.

    Bear in mind when disconnecting a socket you have to do it in a certain way otherwise the close will be unclean. Read MSDN (either its in connect or shutdown) how to do this properly.

    Darwen.

  11. #11
    Join Date
    Jan 2002
    Location
    Scaro, UK
    Posts
    5,940
    Oh, and why do you need to check the status of the socket ? If you haven't received a close notification then the socket is live. This works in 99.99% of cases : the only times I've found when close sockets aren't send is either when you pull the power lead out from the back of the machine or when there's been a catastrophic OS shutdown.

    Even in these cases, when you call 'send' afterwards it flushes a close message through anyway.

    You could of course just do a send of a small amount of data that your server will ignore. This'll check the connection for you.

    Darwen.

  12. #12
    Join Date
    Jul 2001
    Location
    Trutnov, Czech Republic
    Posts
    459
    Originally posted by darwen
    You can use WSAEventSelect etc in winsock to do event notification through events, and then you don't need windows.

    However you will need threads to constantly wait for messages and then pass them back to your main thread.
    Well, that's what I meant - use WSAAsyncSelect to receive events.

    However you will need threads to constantly wait for messages and then pass them back to your main thread.
    What exactly does the scenario look like? That is, what will be the job of the main thread, what will be the job of worker threads...some scheme would be great.

    Thanks.

  13. #13
    Join Date
    Jul 2003
    Location
    Korea
    Posts
    60
    Thank you darwen for your reply. I already both know what you said.

    MSDN says: WSAWOULDBLOCK is return that means that CAsyncSocket is doing something, and if connect successfully, OnConnect(UINT errorCode) will be called. This is , I think, why this class is called "asynchonous" (CSocket always return the desired value). But if fact, it work differently, errorCode is the same return value of CAsyncSocket::Connect(...). So this way to check connection status is impossible. If there is any hidden thing, please let me know.

    Another way, I can check easily connection status at connect(...) statement. By sending handshaking data to server, if no reply, connection could not be established. Handshaking protocol is server-specific, and it can not be generalized. This is similar to your idea:
    You could of course just do a send of a small amount of data that your server will ignore. This'll check the connection for you
    Another solution, I think that we should reimplement CAsyncSocket by using winsock library not the MFC library. This solution seems not suitable with my project's scope.
    Quang

  14. #14
    Join Date
    Jan 2002
    Location
    Scaro, UK
    Posts
    5,940
    Yep, I'd re-implement CAsyncSocket as well. In fact have done so. But I can't post the code here since it's part of a commercial project.

    WSAEventSelect and WSAAsyncSelect are different ways of handling network notifications :

    WSAAsyncSelect passes messages to a window which can sit on the main thread of the application. In cases of client/server mechanisms with low load/quick turnaround of functions in server then it should be fine.

    WSAEventSelect uses an event-driven mechanism which is window independent. It's designed so you can have threads waiting for network events to be passed through to them - it doesn't rely on windows so you can use worker threads if you wish.

    Darwen.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured