How can I use sockets without callbacks?
Cash GEDNY -- ccoyne@equityny.ml.com Thursday, March 27, 1997 Environment: NT 3.51 Visual C++ 4.0 In using sockets, I want to be able to have a DLL that handles socket communications for my apps. One of the things I want this DLL to be able to do is to have a send method that the app calls and then the send method would return the results of my socket send (i.e. from the Receive), so that the app does not have to provide a callback function. Everything I've tried so far just seems to hang up the system (using regular callbacks, response time is instantaneous). Does anyone have any suggestions about how to go about this or can point me in the right direction? TIA, C Coyne ccoyne@gedny.ml.com
Paul Gerhart -- pgerhart@voicenet.com Friday, March 28, 1997 [Mini-digest: 2 responses] Coyne, Cash ( GEDNY) wrote: > > Environment: NT 3.51 Visual C++ 4.0 > > In using sockets, I have two sample sockets, MFC 4.0, VC++ 4.0, Win95 programs that are Freeware. They live at http://www.voicenet.com/~pgerhart/_shware.html Neither uses a hand-crafted DLL - you make no claim as to why that is of benefit. Also, neither uses CSocket. Both are tutorials that I wrote for my own benefit. The first example is called SockTest and it is at http://www.voicenet.com/~pgerhart/socktst2.zip It features a CWnd derived class wrapper around the sockets API. Donald C. Asonye wrote that class as freeware. SockTest is a client that lets you ping, get HTML source etc. from a server. The second example is called MiniFTP and it is at http://www.voicenet.com/~pgerhart/miniftp1.zip It uses the API directly (not Donald's class wrapper) in the Asynchronous fashion (i.e. driven by the Windows message pump). It is an actual FTP client done as a tutorial. Don't expect to tolerate every wacky condition imaginable but it will let you up/down load ASCII or binary files. Both are simple CView apps - while they are 32 bit, no Win32 common controls are used. If you want to stay a 4.0 then these may be of help. Hope this helps. I want to be able to have a DLL that handles socket > communications for my apps. One of the things I want this DLL to be able > to do is to have a send method that the app calls and then the send method > would return the results of my socket send (i.e. from the Receive), so that > the app does not have to provide a callback function. Everything I've > tried so far just seems to hang up the system (using regular callbacks, > response time is instantaneous). > > Does anyone have any suggestions about how to go about this or can point me > in the right direction? > > TIA, > > C Coyne > ccoyne@gedny.ml.com -- ######################### # Paul Gerhart # # pgerhart@voicenet.com # ######################### -----From: Dean GrimmUse select() instead of WSAAsyncSelect() to check when data is ready at the socket. I use the following code to check for data on my non-blocking socket (m_s is the socket descriptor) void CBsdStreamSocket::WaitForRecvReady() { fd_set rfds; int nResponse; struct timeval tv = {0,0}; do { FD_ZERO(&rfds); FD_SET(m_s, &rfds); if((nResponse = select(m_s+1,&rfds, 0,0,&tv)) == SOCKET_ERROR) { ErrorLog("CBsdStreamSocket::WaitForRecvReady: Select Error"); } } while(!(nResponse !=0 && FD_ISSET(m_s,&rfds))); } Hope this helps. Dean Grimm Software Engineer / Cortron Corp. ---------- From: Coyne, Cash ( GEDNY) Sent: Thursday, March 27, 1997 5:13 AM To: 'mfc-l@netcom.com' Subject: How can I use sockets without callbacks? Environment: NT 3.51 Visual C++ 4.0 In using sockets, I want to be able to have a DLL that handles socket communications for my apps. One of the things I want this DLL to be able to do is to have a send method that the app calls and then the send method would return the results of my socket send (i.e. from the Receive), so that the app does not have to provide a callback function. Everything I've tried so far just seems to hang up the system (using regular callbacks, response time is instantaneous). Does anyone have any suggestions about how to go about this or can point me in the right direction? TIA, C Coyne ccoyne@gedny.ml.com
John Moulder -- jm@wg.icl.co.uk Tuesday, April 01, 1997 Take a look at WSAAsyncSelect(). This allows you to register a user defined message (WM_USER + xxx) that is sent to your window's message handler when a specific socket event, or events occur. The trick is to set some flags in your window's message handler according to each socket notification, and check these flags in a message loop within your DLL's send/receive function. The example below is in C pseudo code. switch (message) { case WM_SOCKET_NOTIFY : { switch (WSAGETSELECTEVENT(lParam)) { case FD_READ : bCanRead = TRUE; break; case FD_WRITE : bCanWrite = TRUE; case FD_CONNECT : bConnecting = FALSE; default : ... } } } When reading and writing, you need to await the appropriate socket notification before calling recv() or send(). bCanWrite = FALSE; if (SOCKET_ERROR != WSAAsyncSelect(sd, hwnd, WM_SOCKET_NOTIFY, FD_READ | FD_CLOSE)) { /* * MESSAGE LOOP * * await the asynchronous notification message * and allow other applications to run. */ while (GetMessage(&msg, NULL, 0, 0)) { /* handle the message normally */ TranslateMessage(&msg); /* Send it to our window */ DispatchMessage(&msg); if (bCanWrite) { /* cancel the asynchronous select */ WSAAsyncSelect(_sd, _hwnd, 0, 0); break; } } /* while */ // now do the send() send(...); } Repeat the above with FD_READ notifications to do the recv(). Of course, the error management is omitted from this example for clarity! And if your code is in a DLL, your should consider if you will have multiple, concurrent calling applications, and so require the state information (bCanWrite etc) per task or per socket connection. You may be able to get some advantage from C++ and MFC's classes; I don't know as I did it in raw C and WinSock calls. ---------- > From: Coyne, Cash ( GEDNY)> To: 'mfc-l@netcom.com' > Subject: How can I use sockets without callbacks? > Date: 27 March 1997 14:13 > > Environment: NT 3.51 Visual C++ 4.0 > > In using sockets, I want to be able to have a DLL that handles socket > communications for my apps. One of the things I want this DLL to be able > to do is to have a send method that the app calls and then the send method > would return the results of my socket send (i.e. from the Receive), so that > the app does not have to provide a callback function. Everything I've > tried so far just seems to hang up the system (using regular callbacks, > response time is instantaneous). > > Does anyone have any suggestions about how to go about this or can point me > in the right direction? > > TIA, > > C Coyne > ccoyne@gedny.ml.com > > >
Andrew L. Snow -- als@fl.net.au Wednesday, April 02, 1997 [Mini-digest: 2 responses] > From: Coyne, Cash ( GEDNY)> Subject: How can I use sockets without callbacks? > Date: 27 March 1997 14:13 > Environment: NT 3.51 Visual C++ 4.0 > In using sockets, I want to be able to have a DLL that handles socket > communications for my apps. One of the things I want this DLL to be able > to do is to have a send method that the app calls and then the send method > would return the results of my socket send (i.e. from the Receive), so that > the app does not have to provide a callback function. Everything I've > tried so far just seems to hang up the system (using regular callbacks, > response time is instantaneous). Once again, the Visual C++ online help :-) If using MFC is OK (you don't specifically state it isn't) then check out CSocket. It makes your life easier by blocking (ie. the calls to read/write/connect don't return unless something has actually happened). So what I have done is start a thread which will handle all your communications, then: CSocket mysocket; mysocket.Create(); mysocket.Connect(address, port); // address can be name or IP number The last function returns 0 if theres an error. After it has connected, you can either use mysocket.Send() and mysocket.Receive() or use a CSocketFile to trick yourself into thinking its a file you're reading/writing to, not a socket. But for send ::Send() and ::Receive(), the examples are: char buf[]="Hmmm... "; mysocket.Send(buf, strlen(buf) ); the call returns 0 or SOCKET_ERROR if there's a problem. and to receive 128 bytes, char buf[128]; mysocket.Receive(buf, 128); the call returns the number of bytes read, SOCKET_ERROR if there's an error, or zero if the other end closed. Again, see the online help for details. The help says that if you use CSocket, your messages are still pumped so in theory you don't have to create a thread. In practice a thread may be a better idea, so your interface is more responsive. The "Windows Sockets: Sequence of operations" article is particularly useful. -----From: "Jay F." Or you may just want to consider using threads and turn off notifications. Just make sure your socket is blocking. With threads there is no reason to worry about using AsyncSelect calls, or using a notification when messages come in. When a message arrives, the socket unblocks, you read it , stick it on a queue, and block again. -- Jay Ferguson (Because the Best Things in The Net are FREE) http://www.cse.psu.edu/~ferguson jhf@hrb.com John Moulder wrote: Take a look at WSAAsyncSelect(). This allows you to register a user defined message (WM_USER + xxx) that is sent to your window's message handler when a specific socket event, or events occur. The trick is to set some flags in your window's message handler according to each socket notification, and check these flags in a message loop within your DLL's send/receive function. The example below is in C pseudo code. switch (message) { case WM_SOCKET_NOTIFY : { switch (WSAGETSELECTEVENT(lParam)) { case FD_READ : bCanRead = TRUE; break; case FD_WRITE : bCanWrite = TRUE; case FD_CONNECT : bConnecting = FALSE; default : ... } } } When reading and writing, you need to await the appropriate socket notification before calling recv() or send(). bCanWrite = FALSE; if (SOCKET_ERROR != WSAAsyncSelect(sd, hwnd, WM_SOCKET_NOTIFY, FD_READ | FD_CLOSE)) { /* * MESSAGE LOOP * * await the asynchronous notification message * and allow other applications to run. */ while (GetMessage(&msg, NULL, 0, 0)) { /* handle the message normally */ TranslateMessage(&msg); /* Send it to our window */ DispatchMessage(&msg); if (bCanWrite) { /* cancel the asynchronous select */ WSAAsyncSelect(_sd, _hwnd, 0, 0); break; } } /* while */ // now do the send() send(...); } Repeat the above with FD_READ notifications to do the recv(). Of course, the error management is omitted from this example for clarity! And if your code is in a DLL, your should consider if you will have multiple, concurrent calling applications, and so require the state information (bCanWrite etc) per task or per socket connection. You may be able to get some advantage from C++ and MFC's classes; I don't know as I did it in raw C and WinSock calls. ---------- > From: Coyne, Cash ( GEDNY) > To: 'mfc-l@netcom.com' > Subject: How can I use sockets without callbacks? > Date: 27 March 1997 14:13 > > Environment: NT 3.51 Visual C++ 4.0 > > In using sockets, I want to be able to have a DLL that handles socket > communications for my apps. One of the things I want this DLL to be able > to do is to have a send method that the app calls and then the send method > would return the results of my socket send (i.e. from the Receive), so that > the app does not have to provide a callback function. Everything I've > tried so far just seems to hang up the system (using regular callbacks, > response time is instantaneous). > > Does anyone have any suggestions about how to go about this or can point me > in the right direction? > > TIA, > > C Coyne > ccoyne@gedny.ml.com > > >
Become an MFC-L member | Вернуться в корень Архива |