用
WSAStartup,需要在StdAfx.h头文件中需要声明
#include <WinSock2.h>
#pragma comment(lib,"WS2_32.lib")
#pragma comment(lib,"WS2_32.lib")
用AfxSocket,需要在StdAfx.h头文件中需要声明
#include <afxsock.h>
用到了两种,则需要:
#include <WinSock2.h>
#pragma comment(lib,"WS2_32.lib")
#pragma comment(lib,"WS2_32.lib")
#include <afxsock.h>
上述方法是否可行,需要验证?(在三门峡自动化收购管理系统中,用到了上述内容)
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
);
}
}