2007-1-6~2007-1-8,winlin
摘要:
本文翻译了msdn的socket一些基本知识,并着手写了三个版本的socket程序:1.简单的socket连接。2.发送和接受数据的socket。3.一个多人聊天室。供大家参考。
本文及实例程序下载地址
SOCKET技术... 1
一.Windows Sockets:背景知识... 2
1.SOCKET的定义... 3
2.SOCKET数据类型... 3
3.SOCKET的应用领域... 3
二.WSAStartup函数... 4
参数:... 4
注意... 4
返回值... 5
错误码... 5
三.WSACleanup函数... 5
注意... 6
返回值... 6
错误码... 6
四.socket函数... 6
参数... 6
注意... 7
返回值... 7
错误码... 7
五.bind函数... 7
参数... 7
注意... 7
返回值... 8
错误码... 8
六.sockaddr结构体... 8
注:... 9
七.listen函数... 9
参数:... 9
注意:... 9
返回值:... 10
错误码:... 10
八.accept函数... 10
参数:... 10
注意:... 10
返回值:... 11
错误码:... 11
九.connect函数... 11
参数:... 11
注意:... 11
返回值:... 12
错误码:... 13
十.send函数... 13
参数:... 13
注意:... 13
返回值:... 14
错误码:... 14
十一.recv函数... 15
参数:... 15
注意:... 15
返回值:... 16
错误码:... 16
十二.实例... 16
1.任务:... 16
2.硬件条件:... 16
3.软件环境:... 17
4. 基本的accept-connect的client/server模型:... 17
5. 基本的send/recv的client/server模型:... 20
6. 基本的多线程处理,模拟一个多人聊天室:... 22
十三.总结... 28
这篇文章介绍了WindowsSockets的目的和历史,包括三个内容:
socket的定义。
SOCKET句柄类型的描述。
socket的应用领域。
WindowsSockets规范为Windows定义了一套面向字节兼容的网络编程接口。WindowsSockets基于UNIX socket(伯克利软件发行机构,BSD,release 4.3)实现上。该规范包含了BSD风格的socket和Windows的扩展规范。使用WindowsSockets能保证你的程序能通过任何网络通信,只要网络能支持WindowsSocketsAPI。在Win32中,WindowsSockets是线程安全的。
许多软件商在协议层支持WindowsSockets,包括TCP/IP、XNS、DECNet、IPX/SPX以及其他的协议。尽管WindowsSockets规范定义了TCP/IP的抽象,其他网络协议也能和WindowsSockets一致,只要这些协议能提供它自己的DLL实现。使用WindowsSockets的典型商业应用程序案例包括:XWindowServer,终端仿真,和电子邮件系统。
说明:请记住WindowsSockets的目的是为了抽象网络底层通信协议,所以你不一定要对底层协议非常了解,你的程序也能运行在任何支持sockets的网络上。因此,本文不讨论详细的网络通信协议。
MFC提供了两个类来支持使用WindowsSocketsAPI编程。其中之一是CSocket,提供一个高层次的抽象来简化你的网络通信编程。更多MFC支持socket的信息,请参考:Windows Sockets网络编程,概览。
Windows Sockets规范:Windows下的网络计算开放规范接口,现在是1.1版本,是作为一个开放的网络标准来开发的,由很大数目的个人和组织在TCP/IP开发,并且是免费使用。Socket编程现在编程了社区的一个交流专题,在网络协议板块下。规范在Win32SDK中可用。
提示:由于socket使用Internet协议簇,所以它是计划运行在“信息高速公路”的程序的开发者的首选。
Socket是网络通信的端点(endpoint)――Widows Sockets应用程序通过它来发送或者接受网络数据包。一个socket有一个类型,并且和一个运行的进程关联,它也可能有一个名字。目前为止,socket一般只是和socket交流数据,他们使用的是Internet协议簇。
两边的Socket都是双向的:他们是能在两个方向传递的数据流(全双工)。
两个socket类型可以使用:
Stream Socket:
Stream Socket为不记录边界的数据流提供――字节流。流保证被投递并且正确的序列和不重复的投递。
Datagram Socket:
Datagram Socket支持面向记录的数据流,不保证被正确投递,并且可能不会按照发送的序列达到,也可能重复。
“正确的序列”意思是包按照它们被发送的次序到达。“不重复的投递”意思是对于每个唯一的包你只会收到一次。
提示:一些网络协议,如XNS,流能面向记录――记录的流而不是字节流。尽管在TCP/IP协议中是字节流,windows sockets提供一定层次和底层协议无关的抽象。
若你需要了解这些类型,以及在何种情况下应该用何种socket,请参考:windows socket:stream socket和windows sockets:datagram socket。
每个MFC socket对象封装了一个Windows sockets对象的句柄。这个句柄的类型是SOCKET。SOCKET类型和窗口的HWND非常类似。MFC socket类提供了在这个封装的句柄的操作。
SOCKET数据类型在win32 sdk中有详细的说明。请参考windows socket主题下的socket数据类型和错误代码。
Socket非常有用,至少在下面三个领域:
Client/Server模型
对等网络,如聊天程序。
RPC调用,调用应用程序象调用函数一样方便。
提示:使用MFC socket的情况是通信的两端都可以使用MFC编写:两边都用MFC。关于这个主题的更多信息,以及如何处理和非MFC应用程序通信的问题,请参考:windows sockets:字节序列。
Windows sockets函数WSAStartup对进程初始化WS2_32.DLL的使用。
int WSAStartup(
WORD wVersionRequested,
LPWSADATA lpWSAData
);
wVersionRequested
[in]windows sockets支持调用者能使用的最高版本。高位标出了次版本,低位标出了主版本。
lpWSAData
[out]一个指向WSAData的指针,用来获取windows socket的实际的详细信息。
WSAStartup必须是第一个被程序或者DLL调用的windows sockets函数。它允许程序或者DLL确定使用的windows sockets版本,并且返回实际的windows sockets版本。程序或者DLL必须在调用WSAStartup调用成功后才能调用其他windows sockets函数。
为了支持高版本的windows sockets实现,以及功能上和当前sockets版本不同的应用程序,WSAStartup定义了一些规则。应用程序、WSAStartup和WS2_32.DLL指出它们能支持的最高版本,并确认对方的最高版本是可接受的。在调用WSAStartup时,WS2_32.DLL检查程序所需要的版本。若版本比DLL所支持的最低版本要高,则调用成功,DLL在wHighedVersion存储返回它支持的最高版本,wVersion中返回最小版本支持和请求的wVersionRequested。若WSAData的wVersion字段对于应用程序不能使用,应该调用WSACleanup或者寻找其他的DLL或者直接报告错误消息。
程序可以请求一个比当前规范更高的版本,这种情况下,程序只能使用高版本中的功能。为了适应未来的版本,程序应该完全的适应未来的版本,例如重新编译,链接一个新的DLL,或者其他的情况。
下面的规则允许WS2_32.DLL和windows sockets程序支持一个范围的windows sockets版本。若存在一个版本重叠,则程序能调用一定范围版本的WS2_32.DLL。下图给出了WSAStartup在DLL版本和给定的版本之间的一些选择结果:
DLLVersion 程序要求 选择结果
1.1 1.1 1.1
1.0 1.1 1.0
1.0 1.1 1.0 1.0
1.0 1.1 1.1 1.1
1.0 1.1 调用失败
1.1 1.0 不支持
1.1 2.0 1.1
2.0 2.0 2.0
下面的实例代码演示了程序怎样调用WSAStartup来支持2.2版本的DLL:
WORD wVersionRequested;
WSAData wsaData;
int err;
wVersionRequested = MAKEWORD(2,2);