这两天在研究
Windows Socket
编程,今天总算有了一点突破,把自己做的东西发上来。
CAsyncSocket
类在非常低的级别上封装
Windows Sockets API
。
CAsyncSocket
适合那些对网络通信细节很了解,但希望利用回调的便利通知网络事件的程序员使用。如果想利用
Windows Sockets
方便地处理
MFC
应用程序中的多个网络协议,而又不想放弃灵活性,可以考虑使用
CAsyncSocket
。
本文介绍如何用
CasyncSocket
类进行双机通信应用程序的开发。后面附有源程序。
要使用
CasyncSocket
进行通信,首先我们需要创建一个
SOCKET
。可以使用
CasyncSocket
的
Create()
方法。
构造一个
CAsyncSocket
对象并使用该对象创建基础
SOCKET
句柄。
套接字的创建遵循两阶段构造的
MFC
模式。
例如:
CAsyncSocket sock;
sock.Create( );
//
Use the default parameters
-
或
-
CAsyncSocket
*
pSocket
=
new
CAsyncSocket;
int
nPort
=
27
;
pSocket
->
Create( nPort, SOCK_DGRAM );
上面的第一个构造函数在堆栈上创建一个
CAsyncSocket
对象,第二个构造函数在堆上创建
CAsyncSocket
。上面的第一个
Create
调用使用默认参数创建流式套接字,第二个
Create
调用创建具有指定端口和地址的数据文报套接字。(任一个
Create
版本都可以和任一种构造方法一起使用。)
Create
的参数有:
“
端口
”
:短整型。
对于服务器套接字,必须指定端口
。对于客户端套接字,通常接受此参数的默认值,该值允许
Windows Sockets
选择端口。
套接字类型:
SOCK_STREAM
(默认值)或
SOCK_DGRAM
。
套接字
“
地址
”
,如
“ftp.microsoft.com”
或
“128.56.22.8”
。
该地址为网络上的网际协议
(IP)
地址。很可能要始终依赖此参数的默认值。
SOCKET
创建完之后就可使使用了。如果是客户端就可以使用
CAsyncSocket::Connect
将此套接字对象连接到服务器套接字。如果是服务器端就可以使用使用
CAsyncSocket::Listen
侦听来自客户端的连接尝试。接收到连接请求时,用
CAsyncSocket::Accept
接受该请求。
注意
Accept
成员函数采用对新的空
CSocket
对象的引用作为它的参数。在调用
Accept
之前,必须构造该对象。如果此套接字对象超出范围,则连接关闭。
销毁
CAsyncSocket
对象。
如果在堆栈上创建了套接字对象,当包含函数超出范围时将调用此对象的析构函数。如果使用
new
运算符在堆上创建
了套接字对象,则您必须负责使用 delete 运算符销毁此对象。
析构函数在销毁对象之前调用对象的
Close
成员函数。
当连接建立的时候,就可以进行通信了。
CasycnSocket
类提供以下需要重载的成员函数。
连接建立之后,就可以通过
send()
和
receive()
进行数据的收发
(
当为
TCP
连接的时候
)
,通过
Sendto()
和
ReceiveFrom
()
收发数据,当为
UDP
连接的时候。
废话少说,放上我的例程,整个程序的主要部份就是自己构造的一个新类
CmySocket()
进行通信。里面传递了当前聊天窗体的句柄句柄,以便使用回调函数调用窗体类进行事件响应。
程序不是很大,有兴趣的朋友可以和我联系。
源程序下载
最后附上通讯的流程。
服务器
|
客户端
|
// construct a socket
CSocket sockSrvr;
|
// construct a socket
CSocket sockClient;
|
// create the SOCKET
sockSrvr.Create(nPort); 1,2
|
// create the SOCKET
sockClient.Create( ); 2
|
// start listening
sockSrvr.Listen( );
|
|
|
// seek a connection
sockClient.Connect(strAddr, nPort); 3,4
|
// construct a new, empty socket
CSocket sockRecv;
// accept connection
sockSrvr.Accept( sockRecv ); 5
|
|
// construct file object
CSocketFile file(&sockRecv);
|
// construct file object
CSocketFile file(&sockClient);
|
// construct an archive
CArchive arIn(&file, CArchive::load);
-
或 -
CArchive arOut(&file, CArchive::store);
-
或两者 -
|
// construct an archive
CArchive arIn(&file, CArchive::load);
-
或 -
CArchive arOut(&file, CArchive::store);
-
或两者 -
|
// use the archive to pass data:
arIn >>dwValue;
-
或 -
arOut < < dwValue; 6
|
// use the archive to pass data:
arIn >>dwValue;
-
或 -
arOut < < dwValue; 6
|
1. 这里的 nPort 是端口号。有关端口的详细信息,请参见 Windows Sockets:端口和套接字地址。
2. 服务器必须始终指定一个端口,以便客户端可以连接。 Create 调用有时也指定地址。在客户端使用默认参数,这些参数要求 MFC 使用任何可用端口。
3. 这里的 nPort 是端口号, strAddr 是计算机地址或网际协议 (IP) 地址。
4. 计算机地址可以采用几种形式:“ftp.microsoft.com”、“microsoft.com”。IP 地址采用“以点分隔的数字”形式,如“127.54.67.32”。 Connect 函数查看地址是否为以点分隔的数字(但它不确保该数字是网络上的有效计算机)。如果不是,则 Connect 使用其他某种形式的计算机名称。
5. 当在服务器端调用 Accept 时,传递对新套接字对象的引用。必须首先构造该对象,但不对它调用 Create 。注意,如果此套接字对象超出范围,则连接关闭。MFC 将新对象连接到 SOCKET 句柄。可以在堆栈上构造此套接字(如表中所示)或在堆上构造。
6. 存档和套接字文件在超出范围时将被关闭。套接字对象超出范围或被删除时,对象的析构函数也对此套接字对象调用 Close 成员函数。有关顺序的其他说明