标准TCPIP编程接口-Socket.ppt
《标准TCPIP编程接口-Socket.ppt》由会员分享,可在线阅读,更多相关《标准TCPIP编程接口-Socket.ppt(100页珍藏版)》请在三一办公上搜索。
1、第17章 标准TCP/IP编程接口 Socket,第17章 标准TCP/IP编程接口 Socket,17.1 套接口概述17.2 地址与地址操作函数17.2.1 INET协议族地址结构sockaddr_in17.2.2 IPv4地址结构in_addr17.2.3 通用地址结构sockaddr17.2.4 地址操作函数17.3 端口17.4 字节序问题17.5 三种套接口类型和两种I/O模式17.5.1 套接口的类型17.5.2 I/O模式,第17章 标准TCP/IP编程接口Socket,17.6 基本套接口函数 17.7 简单的客户端程序17.6.1 WSAStartup 17.7.1 UDP
2、客户端17.6.2 socket 17.7.2 TCP客户端17.6.3 bind17.6.4 listen.17.6.5 accept17.6.6 conect17.6.7 recv和send17.6.8 recvfrom和sendto17.6.9 closesocket17.6.10 WSACleanup,17.1 套接口概述,Berkeley sockets 接口在windows平台上的移植版本称为Winsock。最初的伯克利套接口API在windows平台上的移植版本是Winsock1.1,在它的基础上,微软又进一步提供了Winsock2.0从用户的角度来看,套接口是网络通信端点的一种
3、抽象概念,为用户提供一种发送和接收数据的机制。是一种进程间通信的机制,适用于分布式环境。,17.2.1 INET协议地址结构sockaddr_in,struct sockaddr_inShort sin_family;U_short sin_port;Struct in_addr sin_addr;Char sin_zero8;,地址族,一般填AF_INET,16位IP端口,32位IP地址,8个字节的0填充,给结构体初始化清0的函数如下Void*memset(void*dest,int c,size_t count);,所以是TCP/IP,17.2.2 IPv4地址结构in_addr,stru
4、ct in_addrUnionstructu_char s_b1,s_b2,s_b3,s_b4;s_un_b;structu_short s_w1,s_w2;s_un_w;u_long s_addr;s_un;#define;如多网卡,又不关心接口(INADDR_ANY的使用,P184),赋值时的不同分段(4、2、1),INET协议地址结构中的IP地址部分,17.2.3 通用地址结构sockaddr,struct sockaddru_short sa_family;char sa_data14;一种是只为TCP/IP,另外是为了提供通用接口以服务多种网络协议开发的通用结构,但要提供足够的信息说
5、明自己的协议,复杂!例如:Int connetct(socket s,const struct sockaddr FAR*name,int namelen)对于程序员来说,很少直接使用这种通用地址结构。,连接时不是struct sockadr_in*而是通用地址结构,17.2.4 地址操作函数,3个常用的地址操作函数:将点分格式的IPv4地址字符串转化为in_addr地址结构适用的32位整数:unsigned long inet_addr(const char FAR*cp);将in_addr地址值转化为标准的点分IP地址字符串:char FAR*inet_ntoa(struct in_add
6、r in);域名解析功能:struct hostent FAR*gethostbyname(const char FAR*name);注意:在使用winsock函数之前,应用程序必须首先调用WSAStartup函数初始化ws2_32.dll,而在应用结束后必须调用WSACleanup函数关闭。,Hostent结构,struct hostent char FAR*h_name;/*official name of host*/char FAR*FAR*h_aliases;/*alias list*/short h_addrtype;/*host address type*/short h_len
7、gth;/*length of address*/char FAR*FAR*h_addr_list;/*list of addresses*/#define h_addr h_addr_list0/*address,for backward compat*/;,17.3 端口,0:不使用11023:知名端口10245000:可以被任意客户端程序使用500165535:为其他服务器程序预留,17.4 字节序问题,字节顺序转换htons()Host to Network Short“(16bit)htonl()Host to Network Long“(32bit)ntohs()Network t
8、o Host Shortntohl()Network to Host Long连接过程是通过一系列状态表示的,这些状态有:LISTEN,SYN-SENT,SYN-RECEIVED,ESTABLISHED,FIN-WAIT-1,FIN-WAIT-2,CLOSE-WAIT,CLOSING,LAST-ACK,TIME-WAIT 和CLOSED。,17.5.1 三种套接口类型,流套接口(SOCK_STREAM)面向连接的TCP数据报套接口(SOCK_DGRAM)无连接的UDP原始套接口(SOCK_RAW)可以读写ICMP、IGMP报文,可以用于从IP头起构造自己的报文。,17.5.2 I/O模式,非阻
9、塞套接字是指执行此套接字的网络调用时,不管是否执行成功,都立即返回。比如调用某个函数读取网络缓冲区中数据,不管是否读到数据都立即返回,而不会一直挂在此函数调用上。阻塞调用是指调用结果返回之前,当前线程会被挂起。函数只有在得到结果之后才会返回。,17.5.2 I/O模式,简明扼要的来说可以打个比方:你有数个同学来访,有若干数据需要收取:1、你时不时的去门口看看,没有看到你同学的话就回客厅等待,看到同学就接到客厅来,非阻塞模式,无论收到数据与否都返回。2、你一直在门口等着你同学,接到后才回客厅,阻塞模式,接收到数据后才返回。,17.5.2 I/O模式,阻塞(BLOCK):便于使用非阻塞(NONBL
10、OCK):效率较高默认情况下,Winsock函数都以阻塞模式工作,17.6 基本套接口函数,例如:TCP服务器程序流程:初始化Winsock创建一个Socket绑定并监听本地的特定端口accept接收客户端的连接在accept操作返回的Socket上进行数据通信关闭Socket最后结束Winsock的使用,17.6 基本套接口函数,WSAStartupSocketBindListenAcceptConnectrecv和sendrecvfrom和sendtoClosesocketWSACleanup,17.6.1 WSAStartup,简述:#include int WSAStartup(WOR
11、D wVersionRequested,LPWSADATA lpWSAData);wVersionRequested:应用程序需要的最高版本,双字节数值型,高位字节指出副版本(修正)号,低位字节指明主版本号。lpWSAData:指向WSADATA数据结构的指针,用来接收Windows Sockets实现的信息。,17.6.1 WSAStartup,注释:WSAStartup()函数必须是应用程序或DLL调用的第一个Winsock函数。成功调用之后才能进一步的调用别的Winsock函数。它允许应用程序或DLL指明Windows Sockets API的版本号及获得特定Windows Socket
12、s实现的细节。,17.6.1 WSAStartup,注释:WSAStartup()的调用过程一方面是初始化ws2_32.dll。另一方面和Winsock库进行版本协商,只有要求的版本=系统支持的最低版本(下限)才成功。并且在wHighVersion中返回系统支持的最高版本,在wVersion中返回系统支持的高版本(上限)和wVersionRequested中的较小者。然后Winsock库就会假设应用程序将使用wVersion。如果WSDATA结构中的wVersion域对调用方来说不可接收,要么去另一个Windows Sockets DLL中搜索,要么初始化失败。,17.6.1 WSAStart
13、up,本协议允许Windows Sockets DLL和Windows Sockets应用程序共同支持一定范围的Windows Sockets版本。如果版本范围有重叠,应用程序就可以成功地使用Windows Sockets DLL。后面的图表给出了WSAStartup()在不同的应用程序和Windows Sockets DLL版本中是如何工作的:,17.6.1 WSAStartup,17.6.1 WSAStartup,返回值:0:成功 否则返回错误代码 注意通常依靠应用程序调用WSAGetLastError()机制获得的错误代码可能不完全,因为Windows Sockets DLL可能没有建立
14、“上一错误”信息储存的客户数据区域。,17.6.1 WSAStartup,错误代码:WSASYSNOTREADY:指出网络通信依赖的网络子系统还没有准备好。WSAVERNOTSUPPORTED:所需的Windows Sockets API的版本未由特定的Windows Sockets实现提供。WSAEINVAL:应用程序指出的Windows Sockets版本不被该DLL支持。,17.6.1 WSAStartup,示例:#pragma comment(lib,“ws2_32.lib”)#include#include Int main(int arge,char*argv)WORD wVers
15、ionReq=MAKEWORD(0,1);/*希望使用0.1版本*/WSAData wsaData;int ret=WSAStartup(wVersionReq,17.6.2 socket,功能:使用前创建一个新的套接字 定义:SOCKET socket(int af,int type,int protocol);返回值:非负整数描述符表示成功,-1表示出错Af指定协议族,一般设为AF_INET,对应internet。Type有三种类型Protocol指定所用的协议,在TCP或UDP编程的时候都取0。,17.6.2 socket,示例:SOCKET sock=socket(AF_INET,SO
16、CK_STREAM,0);SOCKET sock=socket(AF_INET,SOCK_DGREAM,0);SOCKET sock=socket(AF_INET,SOCK_RAW,IPPROTO_ICMP);例如:创建套接字(TCP)不成功就提示if(socket(AF_INET,SOCK_STREAM,0)0)fprintf(stderr,“socket creating errorn”);exit(1);,17.6.3 bind,简述:本函数将一本地的传输层地址与已经创建的套接口联系起来,一般来说,作为客户端程序,不用关心它的本地地址是什么,也就没有必要调用bind函数,系统会在通信前自
17、动选择一个本地地址(10245000)。但服务进程则必须绑定到一个为客户端所知的地址上。,17.6.3 bind,#include int bind(SOCKET s,const struct sockaddr FAR*name,int namelen);s:标识一未捆绑套接口的描述字name:赋予套接口的地址。sockaddr结构定义如下:struct sockaddr u_short sa_family;char sa_data14;namelen:name名字的长度,17.6.3 bind,注释:本函数适用于未连接的数据报或流类套接口,在connect()或listen()调用前使用。当
18、用socket()创建套接口后,它便存在于一个名字空间(地址族)中,但并未赋名。bind()函数通过给一个未命名套接口分配一个本地名字来为套接口建立本地捆绑(主机地址/端口号)。,17.6.3 bind,注释:在Internet地址族中,一个名字包括几个组成部分,对于SOCK_DGREAM和SOCK_STREAM类套接口,名字由三部分组成:主机地址,协议号(显式设置为UDP和TCP)和用以区分应用的端口号。如果一个应用并不关心分配给它的地址,则可将Internet地址设置为INADDR_ANY,或将端口号置为0。如果Internet地址段为INADDR_ANY,则可使用任意网络接口;在有多种主
19、机环境下可简化编程。如果端口号置为0,则WINDOWS套接口实现将给应用程序分配一个值在1024到5000之间的唯一的端口。应用程序可在bind()后用getsockname()来获知所分配的地址,但必需注意的是,getsockname()只有在套接口连接成功后才会填写Internet地址,这是由于在多种主机环境下若干种Internet地址都是有效的。,17.6.3 bind,返回值:如无错误发生,则bind()返回0。否则的话,将返回SOCKET_ERROR,应用程序可通过WSAGetLastError()获取相应错误代码。,17.6.3 bind,错误代码:WSANOTINITIALISE
20、D:在使用此API之前应首先成功地调用WSAStartup()。WSAENETDOWN:WINDOWS套接口实现检测到网络子系统失效。WSAEADDRINUSE:所定端口已在使用中(参见setoption()中的SO_REUSEADDR选项)。,17.6.3 bind,错误代码:WSAEFAULT:namelen参数太小(小于sockaddr结构的大小)。WSAEINPROGRESS:一个阻塞的WINDOWS套接口调用正在运行中。WSAEAFNOSUPPORT:本协议不支持所指定的地址族。WSAEINVAL:该套接口已与一个地址捆绑。WSAENOBUFS:无足够可用缓冲区,连接过多。WSAEN
21、OTSOCK:描述字不是一个套接口。,17.6.3 bind,示例:创建TCP,绑定IP和端口SOCKET sock=socket(AF_INET,SOCK_STREAM,0);Struct sockaddr_in local;Memset(,17.6.3 bind,如果一个应用程序需要把端口捆绑到超过10245000范围的特定端口时,比如rsh需要捆绑到任一保留端口,则可如下编程:SOCKADDR_IN sin;SOCKET s;u_short alport=IPPORT_RESERVED;sin.sin_family=AF_INET;sin.sin_addr.s_addr=0;for(;)
22、sin.sin_port=htons(alport);if(bind(s,(LPSOCKADDR)if(alport=IPPORT_RESERVED/2)/*failall unassigned reserved ports are*/*in use.*/,17.6.4 listen,简述:创建一个套接口并监听申请的连接.#include int listen(SOCKET s,int backlog);S:用于标识一个已捆绑未连接套接口的描述字。backlog:等待连接队列的最大长度。,17.6.4 listen,注释:为了接受连接,先用socket()创建一个套接口,再用listen()为
23、申请进入的连接建立一个后备日志,然后便可用accept()接受连接了。listen()仅适用于支持连接的套接口,如SOCK_STREAM类型的。套接口s处于一种“变动”模式,申请进入的连接请求被确认,并排队等待被接受。这个函数特别适用于同时有多个连接请求的服务器;如果当一个连接请求到来时,队列已满,那么客户将收到一个WSAECONNREFUSED错误。,17.6.4 listen,注释:当没有可用的描述字时,listen()函数仍试图正常地工作。它仍接受请求直至队列变空。当有可用描述字时,后续的一次listen()或accept()调用会将队列按照当前或最近的“后备日志”重新填充,如有可能的话
24、,将恢复监听申请进入的连接请求。,17.6.4 listen,返回值:如无错误发生,listen()返回0。否则的话,返回SOCKET_ERROR错误,应用程序可通过WSAGetLastError()获取相应错误代码。,17.6.4 listen,错误代码:WSANOTINITIALISED:在使用此API之前应首先成功地调用WSAStartup()。WSAENETDOWN:WINDOWS套接口实现检测到网络子系统失效。WSAEADDRINUSE:试图用listen()去监听一个在使用中的地址。WSAEINPROGRESS:一个阻塞的WINDOWS套接口调用正在运行中。WSAEINVAL:该套
25、接口未用bind()进行捆绑,或已被连接。,17.6.4 listen,错误代码:WSAEISCONN:套接口已被连接。WSAEMFILE:无可用文件描述字。WSAENOBUFS:无可用缓冲区空间。WSAENOTSOCK:描述字不是一个套接口。WSAEOPNOTSUPP:该套接口不正常listen()调用。,17.6.5 accept,简述:在一个套接口接受一个连接。#include SOCKET accept(SOCKET s,struct sockaddr FAR*addr,int FAR*addrlen);s:套接口描述字,该套接口在listen()后监听连接。addr:(可选)指针,指
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 标准 TCPIP 编程 接口 Socket
![提示](https://www.31ppt.com/images/bang_tan.gif)
链接地址:https://www.31ppt.com/p-6365601.html