Windows network Programming notes WinSocket API CSocket casyncsocket__ Programming

Source: Internet
Author: User
Tags assert goto set socket

MFC's support for socket programming is quite sufficient, but its documentation is vague. So that most of the features written by VC slightly
Complex network programs, or using APIs. Therefore CAsyncSocket and csocket in fact become problematic, the masses more respectful distance. More than
Good people also, can not bear the waste of resources, specially for the annotation. Friends about blocking, non-blocking, and so on is not very credible.

====================================================

1. MSDN winsocket API function Description: int WSAAsyncSelect (
__in SOCKET S,
__in HWND hwnd,
__in unsigned int wmsg,
__in Long Levent
);

The WSAAsyncSelect function is used to request this ws2_32.dll should send a message to the window hWnd while it detects an Y Network event specified by the Levent parameter. The message that should being sent is specified by the wmsg parameter. The socket for which notification is required are identified by the s parameter.


The WSAAsyncSelect function automatically sets socket s to nonblocking mode, regardless of the value of Levent. To set socket s back to blocking mode, it is the necessary to clear the event record associated with socket s via a call To WSAAsyncSelect with the Levent set to zero. can then call ioctlsocket or WSAIoctl to set the socket back to blocking mode. For more information about how to set the nonblocking socket back to blocking mode, and the ioctlsocket and WSAIoctl funct ions.

=========================================================

2. Windows network Programming Excerpt: Seventh chapter WinSocket I/O methods:

As we mentioned earlier, the Wi n d o w s sockets perform I/O operations in two modes: Locked and unlocked. In lock mode, the WI n S o C functions that perform operations (such as S e n d and r e C v) will wait until the I/O operation completes, and will not return the program immediately (control is returned to the program). In the non locking mode, the Wi n s o ck function returns immediately. So we must take some appropriate steps to make the lock and the unlocked socket meet the requirements of various occasions.
If the application calls the W s a a s y n e c t for a socket, then the socket pattern is automatically changed from "Lock"

As "unlocked", as we have mentioned earlier. So, if you call the WI n S o C ki/o function like W s a R e C V, but there is no data available at that time, it will inevitably cause the call to fail and return W s a E w o U l D B l o C k error. To prevent this, the application should rely on user-defined window messages specified by the U M S g parameter of W s a s y n c S e c T, to determine when the network event type occurs on the socket, and should not be invoked blindly.

===================================================

3. About CSocket, CAsyncSocket MFC source code excerpt:

The analysis code and the actual test know that CSocket is called by default and the Csocket::accept function is blocked

Code is located in files such as AfxSock.h sockcore.cpp afxsock.inl

 Csocket::csocket () {m_pbblocking = NULL;
	M_nconnecterror =-1;

M_ntimeout = 2000; } afxsock_inline BOOL csocket::create (UINT nsocketport, int nsockettype, LPCTSTR lpszsocketaddress) {return CAsyncSoc Ket::create (Nsocketport, Nsockettype, Fd_read | Fd_write | Fd_oob | fd_accept | Fd_connect | Fd_close, lpszsocketaddress); BOOL casyncsocket::create (UINT nsocketport, int nsockettype, long levent, LPCTSTR lpszsocketaddress) {if (Socket (NS
		Ockettype, Levent)) {if (Bind (nsocketport,lpszsocketaddress)) return TRUE;
		int nresult = GetLastError ();
		Close ();
	Wsasetlasterror (Nresult);
return FALSE; BOOL casyncsocket::socket (int nsockettype, long levent, int nprotocoltype, int naddressformat) {ASSERT (M_hsocket = =
	Invalid_socket);
	M_hsocket = socket (naddressformat,nsockettype,nprotocoltype);
		if (M_hsocket!= invalid_socket) {casyncsocket::attachhandle (M_hsocket, this, FALSE);
	Return AsyncSelect (Levent);
return FALSE; BOOL Casyncsocket::asyncselect (Long Levent) {ASSERT (m_hsocket!= invalid_socket);
	_afx_sock_thread_state* pstate = _afxsockthreadstate;      ASSERT (Pstate->m_hsocketwindow!= NULL);
  WSAAsyncSelect
Return WSAAsyncSelect (M_hsocket, Pstate->m_hsocketwindow,wm_socket_notify, Levent)!= socket_error;

}

3. Test code CSocket send and receive files:

1. Send the file

void Csendfiledlg::onbuttonsendfile () {//Todo:add your control notification handler code here CSocket socktemp; Socktemp.create (7803);
    Port is 7803, arbitrary AfxMessageBox ("Start call Listen");
    
    Socktemp.listen (1);//Accept only one connection AfxMessageBox ("Listen function return");    
    
    CSocket Socksend; AfxMessageBox ("Start call with Accept)");//After testing, csocket::accept is a blocking function socktemp.accept (socksend);

    Socktemp has submitted his own pointer address to socksend, so not close AfxMessageBox ("Accept return)");
    CFile file; if (!file. Open ("d:\\movie.mkv", Cfile::moderead)) {AfxMessageBox ("Error opening d:\\test file.")
        ");
        Socksend.close ();
    Return   int nbufsize = 1024 * 5; The default is dial number, 5K.
    When ADSL, this value can be changed greatly approximately equal to download K number, such as 300K int nsize = nbufsize;    

    Lpbyte pBuf = new Byte[nbufsize];
    DWORD dwtemp = 0;
    BOOL btest = socksend.asyncselect (0);//Because CSocket is actually asynchronous, it changes to a synchronized (blocking) way. Socksend.ioctl (Fionbio, &dwtemp);//With IOCtl the first argument to AsyncSelect is 0, see MSDN UINT ulength = file.
    GetLength (); SockSEnd.
    Send (&ulength, 4);//Transfer file size to receiver (client side) int nnumbyte;
    UINT utotal = 0; while (Utotal < ulength) {if (Ulength-utotal < nbufsize) nsize = ulength-utotal;//when less than buffer n The processing file at test time.
        Read (PBuf, nsize);
            Nnumbyte = Socksend.send (PBuf, nsize);//Note nnumbyte is the actual number of bytes sent, do not use nsize as the quasi-if (Nnumbyte = socket_error) { AfxMessageBox ("Send an error.")
            ");
        Goto Labelexit;
    } utotal + = Nnumbyte; AfxMessageBox ("The file was sent successfully.)
");
    Labelexit:delete[] PBuf; File.
    Close ();
Socksend.close ();

 }

3.2 Receive files:

void Crecvfiledlg::onbuttonrecvfile () {//Todo:add your control notification handler code here CFile file; File. Open ("c:\\copymovie.mkv", Cfile::modecreate |
	
	Cfile::modewrite);
	CSocket Sockrecv;
	Sockrecv.create ();
	if (!sockrecv.connect ("127.0.0.1", 7803))//receiver address, if the Internet, can be changed to the actual IP address, the port to the same server end.
		{//connect function returns immediately, does not block AfxMessageBox ("link failed");
	Return
	} DWORD dwtemp = 0;
	Sockrecv.asyncselect (0);
	Sockrecv.ioctl (Fionbio, &dwtemp);//into blocking mode UINT ulength; Sockrecv.receive (&ulength, 4),//transceiver (server-side) file size int nbufsize = 1024 * 5;//with default dialing speed of the Internet download 5K, if ADSL, can be changed to 300K, or press your
	The actual IE download value int nsize = nbufsize;
	Lpbyte pBuf = new Byte[nbufsize];
	int nnumbyte;
	UINT utotal = 0;
		while (Utotal < ulength) {if (Ulength-utotal < nbufsize) nsize = ulength-utotal;
		Nnumbyte = Sockrecv.receive (PBuf, nsize); if (Nnumbyte = = socket_error) {AfxMessageBox ("Receive error.
			");
		Goto Labelexit; } file. Write (PBuf, nnumbyte);
		Utotal + = nnumbyte;//with the actual received byte as the AfxMessageBox ("Receive file succeeded.")
");
	Labelexit:delete[] PBuf; File.
	Close ();
Sockrecv.close ();
 }

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.