《第17章 标准TCPIP编程接口—Socket》由会员分享,可在线阅读,更多相关《第17章 标准TCPIP编程接口—Socket(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,st
4、ruct 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
6、FAR *inet_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 */ shor
7、t h_addrtype; /* host address 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
8、 Short“(16bit)htonl()Host to Network 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)面向连接的TCP数据报套接口(SOCK_DGRAM)无连接的UD
9、P原始套接口(SOCK_RAW)可以读写ICMP、IGMP报文,可以用于从IP头起构造自己的报文。,17.5.2 I/O模式,非阻塞套接字是指执行此套接字的网络调用时,不管是否执行成功,都立即返回。比如调用某个函数读取网络缓冲区中数据,不管是否读到数据都立即返回,而不会一直挂在此函数调用上。 阻塞调用是指调用结果返回之前,当前线程会被挂起。函数只有在得到结果之后才会返回。,17.5.2 I/O模式,简明扼要的来说可以打个比方:你有数个同学来访,有若干数据需要收取: 1、你时不时的去门口看看,没有看到你同学的话就回客厅等待,看到同学就接到客厅来 ,非阻塞模式,无论收到数据与否都返回。 2、你一直
10、在门口等着你同学,接到后才回客厅 ,阻塞模式,接收到数据后才返回。,17.5.2 I/O模式,阻塞(BLOCK):便于使用非阻塞(NONBLOCK):效率较高默认情况下,Winsock函数都以阻塞模式工作,17.6 基本套接口函数,例如:TCP服务器程序流程:初始化Winsock创建一个Socket绑定并监听本地的特定端口accept接收客户端的连接在accept操作返回的Socket上进行数据通信关闭Socket最后结束Winsock的使用,17.6 基本套接口函数,WSAStartupSocketBindListenAcceptConnectrecv和sendrecvfrom和sendto
11、ClosesocketWSACleanup,17.6.1 WSAStartup,简述:#include int WSAStartup ( WORD wVersionRequested, LPWSADATA lpWSAData );wVersionRequested:应用程序需要的最高版本,双字节数值型,高位字节指出副版本(修正)号,低位字节指明主版本号。lpWSAData:指向WSADATA数据结构的指针,用来接收Windows Sockets实现的信息。,17.6.1 WSAStartup,注释: WSAStartup()函数必须是应用程序或DLL调用的第一个Winsock函数。成功调用之后
12、才能进一步的调用别的Winsock函数。 它允许应用程序或DLL指明Windows Sockets API的版本号及获得特定Windows Sockets实现的细节。,17.6.1 WSAStartup,注释: WSAStartup() 的调用过程一方面是初始化ws2_32.dll。另一方面和Winsock库进行版本协商,只有要求的版本=系统支持的最低版本(下限)才成功。并且在wHighVersion中返回系统支持的最高版本,在wVersion中返回系统支持的高版本(上限)和wVersionRequested中的较小者。然后Winsock库就会假设应用程序将使用wVersion。如果WSDAT
13、A结构中的wVersion域对调用方来说不可接收, 要么去另一个Windows Sockets DLL中搜索,要么初始化失败。,17.6.1 WSAStartup,本协议允许Windows Sockets DLL和Windows Sockets应用程序共同支持一定范围的Windows Sockets版本。如果版本范围有重叠,应用程序就可以成功地使用Windows Sockets DLL。 后面的图表给出了WSAStartup()在不同的应用程序和Windows Sockets DLL版本中是如何工作的:,17.6.1 WSAStartup,17.6.1 WSAStartup,返回值: 0:成功
14、 否则返回错误代码 注意通常依靠应用程序调用WSAGetLastError()机制获得的错误代码可能不完全,因为Windows Sockets DLL可能没有建立“上一错误”信息储存的客户数据区域。,17.6.1 WSAStartup,错误代码:WSASYSNOTREADY:指出网络通信依赖的网络子系统还没有准备好。WSAVERNOTSUPPORTED:所需的Windows Sockets API的版本未由特定的Windows Sockets实现提供。WSAEINVAL:应用程序指出的Windows Sockets版本不被该DLL支持。,17.6.1 WSAStartup,示例:#pragma
15、 comment(lib, “ ws2_32.lib”)#include #include 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; ,