VC基于消息的异步套接字

WSAStartup,需要在StdAfx.h头文件中需要声明

#include   
#pragma   comment(lib,"WS2_32.lib")


用AfxSocket,需要在StdAfx.h头文件中需要声明

#include   


用到了两种,则需要:

#include   
#pragma   comment(lib,"WS2_32.lib")

#include   

上述方法是否可行,需要验证?(在三门峡自动化收购管理系统中,用到了上述内容)


1、在【项目名.cpp】文件 BOOL CXxxApp :: InitInstance ()中添加代码:

                 // 加载套接字库

                 WORD wVersionRequested ;

                 WSADATA wsaData ;

                 int err ;

 

                 wVersionRequested = MAKEWORD (2, 2);

                 err = WSAStartup ( wVersionRequested , & wsaData );

                 if ( err != 0)

                {

                                 MessageBox ( NULL , _T ( "启动异步套接字失败!" ), _T ( "提示" ), MB_OK );

                                 return FALSE ;

                }

                 if ( LOBYTE ( wsaData . wVersion ) != 2 || HIBYTE ( wsaData . wVersion ) != 2)

                {

                                 WSACleanup ();

                                 MessageBox ( NULL , _T ( "Socket版本错误!" ), _T ( "提示" ), MB_OK );

                                 return FALSE ;

                }

 

2、析构函数中


CLineControlApp ::~ CLineControlApp ()

{

                 // TODO: add construction code here,

                 // Place all significant initialization in InitInstance

                 WSACleanup ();

}

 


3、在头文件中

 


#define  UM_SOCK                WM_USER  + 1   // Socket接收到信息

 


在类中定义套接字


SOCKET   m_socket  // 套接字描述符

 


BOOL InitSocket ( void );




 


//afx_msg   void  OnSock ( WPARAM   wParam  LPARAM   lParam  );  // VC6


afx_msg   LRESULT  OnSock ( WPARAM   wParam  LPARAM   lParam  );  // VC2005以上





 




 



4、创建并初始化套接字


// 创建并初始化套接字

BOOL CZdhsgDlg :: InitSocket ( void )

{

                 m_socket = WSASocket ( AF_INET , SOCK_DGRAM , 0, NULL , 0, 0);

                 if ( INVALID_SOCKET == m_socket )

                {

                                 MessageBox ( _T ( "套接字创建失败!" ), _T ( "错误" ));

                                 return FALSE ;

                }

                 // 地址结构体

                 SOCKADDR_IN addrSock ;

                 addrSock . sin_family = AF_INET ;

                 addrSock . sin_port = htons (20131);

                 addrSock . sin_addr . S_un . S_addr = htonl ( INADDR_ANY );

                 称重线程接收报错1054,增加该函数

                 DWORD dwBytesReturned = 0;

                 BOOL bNewBehavior = FALSE ;

                 DWORD status ;

                 status = WSAIoctl ( m_socket , SIO_UDP_CONNRESET , & bNewBehavior , sizeof ( bNewBehavior ), NULL , 0, & dwBytesReturned , NULL , NULL );

 

                 // 接收缓冲区

                 int nRecvBuf = 128 * 1024; // 设置为128K

                 setsockopt ( m_socket , SOL_SOCKET , SO_RCVBUF , ( const char *)& nRecvBuf , sizeof ( int ));

                 // 发送缓冲区

                 int nSendBuf = 128 * 1024; // 设置为128K

                 setsockopt ( m_socket , SOL_SOCKET , SO_SNDBUF , ( const char *)& nSendBuf , sizeof ( int ));

 

                 //

                 // 绑定套接字

                 if ( SOCKET_ERROR == bind ( m_socket , ( SOCKADDR *)& addrSock , sizeof ( SOCKADDR )))

                {

                                 MessageBox ( _T ( "绑定套接字失败!" ), _T ( "错误" ));

                                 return FALSE ;

                }

                 // 请求一个基于Windows消息的网络事件通知

                 if ( SOCKET_ERROR == WSAAsyncSelect ( m_socket , m_hWnd , UM_SOCK , FD_READ ))

                {

                                 MessageBox ( _T ( "注册网络读取事件失败!" ), _T ( "错误" ));

                                 return FALSE ;

                }

 

                 return TRUE ;

}

 

 


5、在CPP文件中:

OnInitDialog  ()中加入: InitSocket ();


 






BEGIN_MESSAGE_MAP ( CZdhxtEmulatorDlg , CDialogEx )

                 ON_WM_SYSCOMMAND ()

                 ON_WM_PAINT ()

                 ON_WM_QUERYDRAGICON ()

                 ON_MESSAGE ( UM_SOCK , OnSock ) // 加入这一行代码

END_MESSAGE_MAP ()



 

 

6、OnSock()


LRESULT CZdhsgDlg :: OnSock ( WPARAM wParam , LPARAM lParam )

{

                 CString temp ;

 

                 switch ( LOWORD ( lParam ))

                {

                 case FD_READ :

                                 WSABUF wsabuf ;

                                 wsabuf . buf = new char [200];

                                 wsabuf . len = 200;

                                 DWORD dwRead = 0;

                                 DWORD dwFlag = 0;

                                 SOCKADDR_IN addrFrom ;

                                 int len = sizeof ( SOCKADDR );

                                 // WSARecvFrom接收数据报类型的数据,并保存数据发送方地址

                                 if ( SOCKET_ERROR == WSARecvFrom ( m_socket , & wsabuf , 1, & dwRead , & dwFlag , ( SOCKADDR *)& addrFrom , & len , NULL , NULL ))

                                {

                                                 temp . Format ( _T ( "Socket接收数据失败:%d" ), WSAGetLastError ());

                                                 AddLog ( temp );

                                                 delete [] wsabuf . buf ;

                                                 return FALSE ;

                                }

 

                                 CString address ;

                                 address . Format ( _T ( "%s" ), inet_ntoa ( addrFrom . sin_addr ));

 

                                 if ( dwRead < 1)

                                {

                                                 temp . Format ( _T ( "Socket未接收到数据!来自:%s" ), address );

                                                 AddLog ( temp );

                                                 delete [] wsabuf . buf ;

                                                 return FALSE ;

                                }

 

                                 /*CString str;

                                str.Format(_T("%s\t%s"), inet_ntoa(addrFrom.sin_addr), wsabuf.buf);

                                WriteSgxtLog(str);*/

 

                                 BYTE * data ;       // 保存从接收缓冲区中提取的数据包

                                 data = new BYTE [ dwRead ];

                                 memset ( data , 0, dwRead );

                                 memcpy ( data , wsabuf . buf , dwRead ); // nRevData[0]中存放的是数据包的有效长度lRevDataLen

                                 //CheckReceiveData(address, data, dwRead);

                                 m_dataChecker . CheckReceiveData ( address , data , dwRead , this -> GetSafeHwnd ());

 

                                 delete [] wsabuf . buf ;

                                 break ;

                }

 

                 return TRUE ;

}

 

7、析构函数


CZdhsgDlg ::~ CZdhsgDlg ()

{

                 if ( m_socket )

                {

                                 closesocket ( m_socket );

                }

}




菊子曰 本文用 菊子曰发布

转载于:https://www.cnblogs.com/sdsunjing/p/vc%e5%9f%ba%e4%ba%8e%e6%b6%88%e6%81%af%e7%9a%84%e5%bc%82%e6%ad%a5%e5%a5%97%e6%8e%a5%e5%ad%97.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值