资源预览内容
第1页 / 共61页
第2页 / 共61页
第3页 / 共61页
第4页 / 共61页
第5页 / 共61页
第6页 / 共61页
第7页 / 共61页
第8页 / 共61页
第9页 / 共61页
第10页 / 共61页
亲,该文档总共61页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
Socket(套接字)编程,Socket简介 Windows Socket Linux Socket Socket常用函数介绍 TCP/IP网络程序框架与实例 通信方式 阻塞 非阻塞,为什么需要Socket,普通的I/O操作过程 打开文件读/写操作关闭文件 TCP/IP协议被集成到操作系统的内核中,引入了新型的“I/O”操作 需要一种通用的网络编程接口:Socket 独立于具体协议 BSD Socket(伯克利套接字)是通过标准的UNIX文件描述符和其它程序通讯的一个方法,目前已经被广泛移植到各个平台。,Socket类型,流式套接字(SOCK_STREAM) 提供了一个面向连接(对应TCP协议)。 数据报套接字(SOCK_DGRAM) 提供无连接服务(对应UDP)。 原始套接字(SOCK_RAW) 可以对较低层次协议,如IP、ICMP直接访问(程序员组织包括IP头部等的所有数据)。,Socket的位置,两类系统中使用的Socket,不同操作系统中的Socket Windows Socket (Winsock) Linux Socket (BSD Socket),Windows Socket,简称Winsock,是在Windows环境下使用的一套网络编程规范,基于4.3BSD的BSD Socket API制定 1991年Winsock 1.1,16位,由WINSOCK.DLL支持,主要用在Windows 95中 1997年Winsock 2.2 版,32位,由WSOCK32.DLL支持,主要用在Windows 98及以后的版本中 已经成为Windows环境下网络编程的事实标准 三类函数 与BSD Socket相兼容的基本函数 与BSD Socket相兼容的网络信息检索函数 Windows专用扩展函数,Linux Socket,基本上就是BSD Socket 需要使用的头文件 数据类型:#include 函数定义:#include ,Socket常用函数介绍,基本函数 网络信息检索函数,基本函数,网络连接函数 socket( )创建套接字 bind ( ) 绑定本机端口 connect ( ) 建立连接 listen ( ) 监听端口 accept ( ) 接受连接 recv ( ), recvfrom ( ) 数据接收 send ( ), sendto ( ) 数据发送 closesocket ( ), shutdown ( ) 关闭套接字,基本函数,转换函数 IP地址转换函数 inet_addr()点分十进制数表示的IP地址转换为网络字节序的IP地址 inet_ntoa()网络字节序的IP地址转换为点分十进制数表示的IP地址 字节排序函数 htonl ( ) 4字节主机字节序转换为网络字节序 ntohl ( ) 4字节网络字节序转换为主机字节序 htons ( ) 2字节主机字节序转换为网络字节序 ntohs ( ) 2字节网络字节序转换为主机字节序,网络信息检索函数,gethostname ( ) 获得主机名 getpeername ( ) 获得与套接字相连的远程协议地址 getsockname ( ) 获得套接字本地协议地址 gethostbyname ( ) 根据主机名取得主机信息 gethostbyaddr ( ) 根据主机地址取得主机信息 getprotobyname ( ) 根据协议名取得主机协议信息,网络信息检索函数,getprotobynumber ( ) 根据协议号取得主机协议信息 getservbyname ( ) 根据服务名取得相关服务信息 getservbyport ( ) 根据端口号取得相关服务信息 getsockopt ( ) /setsockopt ( ) 获取/设置一个套接字选项 ioctlsocket ( ) 设置套接字的工作方式,Windows中的Socket编程,Windows中的Socket编程 Winsock 的启动 Winsock API基本函数 TCP/IP网络程序框架(C/S模式) 阻塞与非阻塞通信方式 实例程序说明,Winsock,Winsock是一个基于Socket模型的API,在Windows系统中广泛使用 它在Berkeley接口函数的基础上,还增加了基于消息驱动机制的Windows扩展函数 Winsock1.1只支持TCP/IP网络,Winsock2.2增加了对更多协议的支持,Winsock(2),需要包含头文件Winsock2.h,需要使用库ws2_32.lib,包含办法可以用语句来告诉编译时调用该库 #pragma comment(lib,”ws2_32.lib”); 如果使用Visual C+ 6.0,可以通过“工程” “设置”“工程设置”“链接”“对象/库模块”中加入“ws2_32.lib”,Windows Socket的启动,在调用任何一个Winsock函数之前都必须检查协议栈安装情况,使用函数WSAStartup()完成操作。int WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData); wVersionRequested是一个WORD型(双字节型)数值,指定使用的版本号,对Winsock2.2而言,此参数的值为0 x0202,也可以用宏MAKEWORD(2,2)来获得 lpWSAData是一个指向WSADATA结构的指针,它返回关于Winsock实现的详细信息,Winsock启动示例,#include WORD wVersionRequested; WSADATA wsaData; wVersionRequested=MAKEWORD(2,2); if(WSAStartup(wVersionRequested, /说明WinsockDLL正确加载,可以执行以下代码,创建套接字socket(),应用程序在使用套接字通信前,必须要拥有一个套接字,使用socket()函数来给应用程序创建一个套接字。 SOCKET socket( int af, int type, int protocol );,socket()参数说明,af参数说明套接字要使用的协议地址族。如果想建立一个TCP或UDP,只能用常量AF_INET表示使用互联网协议(IP)地址。 type参数描述套接字的类型,af是AF_INET的时候只能为SOCK_STREAM、SOCK_DGRAM或SOCK_RAW。 protocol说明该套接字使用的特定协议,当协议地址族af和协议类型type确定后,协议字段可以使用的值是限定的。,指定本地地址bind(),当socket()创建了一个套接字后,需要将该套接字与该主机上提供服务的IP地址和某端口联系在一起,bind()函数用于完成这样的绑定。 int bind( SOCKET s, const struct sockaddr FAR * name, int namelen );,bind()参数说明,s标识一个未绑定的套接字描述字,它是socket 函数调用成功时返回的值。 name是一个与指定协议有关的地址结构指针,存储了套接字的地址信息,Winsock中使用sockaddr_in结构指定IP地址和端口信息。 struct sockaddr_in short sin_family; u_short sin_port; struct in_addrsin_addr; char sin_zero8; ,bind()参数说明,sin_family一般为AF_INET,表示使用IP地址族; sin_port是以网络字节序表示的16位端口号; sin_addr是网络字节序的32位IP地址; sin_zero字段一般不用,用0填充 namelen表示地址参数(name)的长度 IP地址参数为INADDR_ANY,则由系统内核来自动指定,port为0,则由系统自动指派一个10245000之间惟一的端口号,bind()实例,#include SOCKET s; sockaddr_in tcpaddr; int iSockErr; int port=5000; /端口号 s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); tcpaddr.sin_family=AF_INET; tcpaddr.sin_port=htons(port); tcpaddr.sin_addr.s_addr=htonl(INADDR_ANY); if(bind(s,(LPSOCKADDR) 函数调用成功,进行其他处理。,服务器端启动监听listen()函数,在一个服务器端: socket()调用成功创建了一个套接字 bind()函数和一个指定的地址关联 接下来需要指示该套接字进入监听连接请求状态,这需要通过listen()函数来实现 int listen(SOCKET s, int backlog); s代表已绑定了地址,还未建立连接的套接字。 backlog指定了正在等待连接的最大队列长度。,客户端请求连接connect()函数,当服务器端建立好套接字并与一个本地地址绑定后,就进入监听状态,等待客户发出连接请求。在客户端套接字建立好之后,就调用connect()函数来与服务器建立连接(省略了bind调用)。 int connect( SOCKET s, const struct sockaddr FAR * name, int namelen); s将要建立连接的套接字描述字 name是一个指向远端套接字地址结构的指针 namelen是服务器端的地址结构长度,即name的长度,Connect()函数的说明,在客户端使用该函数请求建立连接时,将激活建立连接的三次握手,用来建立一条到服务器TCP的连接。如果调用该函数前没有调用bind()来绑定本地地址,则由系统隐式绑定一个地址到该套接字。 该函数UDP协议也可以使用,但并不真正地发出连接请求,用于将使用UDP协议的套接字与服务器的地址关联起来,后续发送数据时,不需要每次都给出服务器地址。,服务器端接受连接accept()函数,服务器端进入监听状态后,调用accept()函数时表示可以接收来自客户端由connect()发出的连接请求,双方进入连接状态。 SOCKET accept(SOCKET s, struct sockaddr FAR * addr, int FAR * addrlen); s标识一个套接字,该套接字处于监听状态 addr是一个地址结构的指针,用来存放发出连接请求的那个客户机的IP地址信息 addrlen指出客户套接字地址结构的长度,发送数据-send()函数,在已经建立连接的套接字上发送数据,可以使用send()函数 int send(SOCKET s, const char FAR * buf, int len, int flags); s用于标识已建立连接的套接字 buf是将要发送的数据 len即将发送的缓冲区中的字节数,send()函数参数说明,flags用于控制数据传输方式,0表示按正常方式发送数据;宏MSG_DONTROUTE说明系统目标主机就在直接连接的本地网络中,无需路由选择;MSG_OOB指出数据是按带外数据发送的。 函数说明:send()函数适用于已建立连接的数据报(流式套接字)发送数据,对于数据报类型套接字必须注意发送数据长度不大于通信子网的IP包最大长度。,接收数据recv()函数,对于已建立连接的套接字来说,要从套接字上接收数据,就要使用recv()函数。 int recv(SOCKET s,char FAR * buf, int len, int flags); flags指定调用的方式。0表示正常接收数据。MSG_PEEK表示会使有用的数据复制到所提供的接收端缓冲区内,但是没有从系统缓冲区中将数据删除。MSG_OOB表示处理带外数据。,无连接的套接
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号