标准TCPIP编程接口—Socket.ppt
《标准TCPIP编程接口—Socket.ppt》由会员分享,可在线阅读,更多相关《标准TCPIP编程接口—Socket.ppt(101页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、标准标准TCPIP编程接口编程接口Socket第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编程接口Socket17.6 基本套接口函数 17.7 简单的客户端程序17.6.1 W
2、SAStartup 17.7.1 UDP客户端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 WSACleanup17.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_INET16位IP端口32位IP地址8个字节的0填充,给结构体初始化清0的函数如下Void*memset(void*dest,int c,size_t count);所以是TCP/IP17.2.2 IPv4地址结构i
4、n_addr struct 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)202.119.9.199赋值时的不同分段(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
6、_ntoa(struct in_addr 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 addres
7、s type*/short h_length;/*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
8、 Long“(32bit)ntohs()Network to 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)l面向连接的TCP数据报套接口(SOCK_DGRAM)l无连接的UDP原始套接口(SOCK_RAW)l可以读写ICMP、IGMP报文,可以用
9、于从IP头起构造自己的报文。17.5.2 I/O模式非阻塞套接字是指执行此套接字的网络调用时,不管是否执行成功,都立即返回。比如调用某个函数读取网络缓冲区中数据,不管是否读到数据都立即返回,而不会一直挂在此函数调用上。阻塞调用是指调用结果返回之前,当前线程会被挂起。函数只有在得到结果之后才会返回。17.5.2 I/O模式 简明扼要的来说可以打个比方:你有数个同学来访,有若干数据需要收取:1、你时不时的去门口看看,没有看到你同学的话就回客厅等待,看到同学就接到客厅来,非阻塞模式,无论收到数据与否都返回。2、你一直在门口等着你同学,接到后才回客厅,阻塞模式,接收到数据后才返回。17.5.2 I/O
10、模式阻塞(BLOCK):便于使用非阻塞(NONBLOCK):效率较高默认情况下,Winsock函数都以阻塞模式工作17.6 基本套接口函数 例如:TCP服务器程序流程:初始化Winsock创建一个Socket绑定并监听本地的特定端口accept接收客户端的连接在accept操作返回的Socket上进行数据通信关闭Socket最后结束Winsock的使用17.6 基本套接口函数WSAStartupSocketBindListenAcceptConnectrecv和sendrecvfrom和sendtoClosesocketWSACleanup17.6.1 WSAStartup 简述简述:#inc
11、lude int WSAStartup(WORD wVersionRequested,LPWSADATA lpWSAData);wVersionRequested:应用程序需要的最高版本,双字节数值型,高位字节指出副版本(修正)号,低位字节指明主版本号。lpWSAData:指向WSADATA数据结构的指针,用来接收Windows Sockets实现的信息。17.6.1 WSAStartup 注释注释:WSAStartup()函数必须是应用程序或DLL调用的第一个Winsock函数。成功调用之后才能进一步的调用别的Winsock函数。它允许应用程序或DLL指明Windows Sockets AP
12、I的版本号及获得特定Windows Sockets实现的细节。17.6.1 WSAStartup 注释注释:WSAStartup()的调用过程l一方面是初始化ws2_32.dll。l另一方面和Winsock库进行版本协商,只有要求的版本=系统支持的最低版本(下限)才成功。并且在wHighVersion中返回系统支持的最高版本,在wVersion中返回系统支持的高版本(上限)和wVersionRequested中的较小者。然后Winsock库就会假设应用程序将使用wVersion。如果WSDATA结构中的wVersion域对调用方来说不可接收,要么去另一个Windows Sockets DLL中
13、搜索,要么初始化失败。17.6.1 WSAStartup 本协议允许Windows Sockets DLL和Windows Sockets应用程序共同支持一定范围的Windows Sockets版本。如果版本范围有重叠,应用程序就可以成功地使用Windows Sockets DLL。后面的图表给出了WSAStartup()在不同的应用程序和Windows Sockets DLL版本中是如何工作的:17.6.1 WSAStartup应用程序版本 DLL版本 wVersionRequested程序要求最高 wVersion程序要求与系统最低的最小值wHighVersion系统最高 最终结果 1.1
14、1.1 1.1 1.1 1.1 use 1.11.0 1.11.0 1.11.01.0use 1.0 1.01.0 1.11.01.01.1use 1.01.1 1.0.1.1 1.11.1 1.1use 1.11.11.01.1 1.01.0失败1.0 1.11.0WSAVERNOTSUPPORTED1.0 1.11.0 1.11.11.11.1use 1.11.1.2.01.12.01.11.1use 1.12.01.12.0 1.1 1.1失败17.6.1 WSAStartup 返回值返回值:0:成功 否则返回错误代码 注意通常依靠应用程序调用WSAGetLastError()机制获得的
15、错误代码可能不完全,因为Windows Sockets DLL可能没有建立“上一错误”信息储存的客户数据区域。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
16、 Int main(int arge,char*argv)WORD wVersionReq=MAKEWORD(0,1);/*希望使用0.1版本*/WSAData wsaData;int ret=WSAStartup(wVersionReq,&wsaData)if(ret!=0)printf(“%dn,ret”)return 1;else printf(“High:%xUse:%xn”,wsaData.wHighVersion,wsaData.wVersion”);WSACleantup();return 0;17.6.2 socket 功能功能:使用前创建一个新的套接字 定义定义:SOCKET
17、 socket(int af,int type,int protocol);返回值:返回值:非负整数描述符表示成功,-1表示出错AfAf指定协议族,一般设为AF_INET,对应internet。Type有三种类型ProtocolProtocol指定所用的协议,在TCP或UDP编程的时候都取0。类型(type)SOCK_STREAMSOCK_DGRAMSOCK_RAM解释字节流套接口数据报套接口原始套接口af=AF_INET时选择的协议TCPUDPIPv417.6.2 socket示例:SOCKET sock=socket(AF_INET,SOCK_STREAM,0);SOCKET sock=s
18、ocket(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函数,系统会在通信前自动选择一个本地地址(10245000)。但服务进
19、程则必须绑定到一个为客户端所知的地址上。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()调用前使用。当用socket()创建套接口后,它便存在于一个名字
20、空间(地址族)中,但并未赋名。bind()函数通过给一个未命名套接口分配一个本地名字来为套接口建立本地捆绑(主机地址/端口号)。17.6.3 bind注释:注释:在Internet地址族中,一个名字包括几个组成部分,对于SOCK_DGREAM和SOCK_STREAM类套接口,名字由三部分组成:主机地址,协议号(显式设置为UDP和TCP)和用以区分应用的端口号。如果一个应用并不关心分配给它的地址,则可将Internet地址设置为INADDR_ANY,或将端口号置为0。如果Internet地址段为INADDR_ANY,则可使用任意网络接口;在有多种主机环境下可简化编程。如果端口号置为0,则WIND
21、OWS套接口实现将给应用程序分配一个值在1024到5000之间的唯一的端口。应用程序可在bind()后用getsockname()来获知所分配的地址,但必需注意的是,getsockname()只有在套接口连接成功后才会填写Internet地址,这是由于在多种主机环境下若干种Internet地址都是有效的。17.6.3 bind 返回值:返回值:如无错误发生,则bind()返回0。否则的话,将返回SOCKET_ERROR,应用程序可通过WSAGetLastError()获取相应错误代码。17.6.3 bind错误代码:错误代码:WSANOTINITIALISED:在使用此API之前应首先成功地调
22、用WSAStartup()。WSAENETDOWN:WINDOWS套接口实现检测到网络子系统失效。WSAEADDRINUSE:所定端口已在使用中(参见setoption()中的SO_REUSEADDR选项)。17.6.3 bind错误代码:错误代码:WSAEFAULT:namelen参数太小(小于sockaddr结构的大小)。WSAEINPROGRESS:一个阻塞的WINDOWS套接口调用正在运行中。WSAEAFNOSUPPORT:本协议不支持所指定的地址族。WSAEINVAL:该套接口已与一个地址捆绑。WSAENOBUFS:无足够可用缓冲区,连接过多。WSAENOTSOCK:描述字不是一个套
23、接口。17.6.3 bind示例:创建TCP,绑定IP和端口SOCKET sock=socket(AF_INET,SOCK_STREAM,0);Struct sockaddr_in local;Memset(&local,0,sizeof(local);local.sin_addr.s_addr=inet_addr(“202.119.9.199”);Local.sin_family=AF_INET;Local.sin_port=htons(9999);If(bind(sock,(struct sockaddr*)&local,sizeof(local)=SOCKET_ERROR)Printf(
24、“Error:%dn”,WSAGetlastError();WSACleanup();Return 1;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(;)sin.sin_port=htons(alport);if(bind(s,(LPSOCKADDR)&sin,sizeof(sin)=0)/*
25、it worked*/if(GetLastError()!=WSAEADDRINUSE)/*fail*/alport-;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()创建一个套接口
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 标准 TCPIP 编程 接口 Socket
限制150内