




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、,网络编程技术,设计、制作:谭献海 Email:,socket(套接字),Socket API ARPA UC Berkeley BSD unix /Berkeley unix De facto standard Example Server Client,一个本地主机建立或拥有的应用程序, 操作系统控制下的,与其它(远程)应用进程之间发送和接收数据的接口,通信协议应用程序接口(APIs)-依赖于操作系统和编程语言 UNIX: Berkeley Sockets (C语言) System V Transport Layer Interface (TLI) (C语言) WINDOWS:WINSOC
2、K,客户端,socket 是进行程序间通讯(IPC)的 BSD 方法。 客户将插头插入一个服务器端口 建立一个双向的连接管道,服务器,插口(port),socket的抽象表示,一些Socket编程的概念,流(Stream) 连接(Connection) 阻塞(Block)、非阻塞(Non-block) 同步(Synchronous)、异步(asynchronous) IP地址 (IP Address) 字节顺序(Bytes Order) 带外数据(Outband Data),需要用到的头文件,数据类型:#include 函数定义:#include ,Berkeley Socket 常用函数列表
3、,网络连接函数 获取/设置socket的参数或信息 转换函数,网络连接函数,socket bind connect listen accept select recv, recvfrom send, sendto close, shutdown,获取/设置socket的参数或信息,gethostbyaddr, gethostbyname gethostname getpeername getprotobyname, getprotobynumber getservbyname, getservbyport getsockname getsockopt, setsockopt ioctl,转换函
4、数,IP地址转换 inet_addr() inet_ntoa() 字节顺序转换 htons()-Host to Network Short htonl()-Host to Network Long ntohs()-Network to Host Short ntohl()-Network to Host Long,socket address structures for Internet,XNS and Unix families,Struct sockaddr_in Struct sockaddr_us,struct sockaddr_un,socket address,The famil
5、y is one of AF_UNIXUnix internal protocols AF_INETInternet protocols AF_NSXerox NS protocols AF_IMPLINKIMP link layer 其中,AF_ 代表“address family” Socket地址的数据部分根据不同的地址类型来解释,常见的地址类型是internet、XNS和UNIX。 对于使用最多的INTERNET簇,其网络地址主要包括两大部分:端口号、IP地址,它的地址结构在中定义,数据结构:sockaddr_in,Internet地址 struct sockaddr_in short
6、 int sin_family; /* Address family */ unsigned short int sin_port; /* Port number */ /* 16-bit port number , network byte ordered */ struct in_addr sin_addr; /* Internet address */ /* 32-bit netid/hosted (IP)地址, network byte ordered */ unsigned char sin_zero 8; /* unused */ ; 该结构与sockaddr兼容,供用户填入参数,
7、程序中实际只填写sockaddr_in结构,struct sockaddr_in my_addr; my_addr.sin_family = AF_INET; my_addr.sin_port = htons(3490); /* short, NBO*/ my_addr.sin_addr.s_addr = inet_addr(0); bzero( 注意:sin_addr.s_addr填本机IP地址,如果此项填INADDR_ANY时,表示自动取本机IP填入该项(仅用于Server),创建一个socket Socket描述符与Linux中的文件描述符类似,也是一个int型的变
8、量 函数调用: int socket(int family, int type, int protocol); 函数返回Socket描述符,返回-1表示出错 family参数一般取AF_INET, protocol参数一般取0 应用示例: TCP:sockfd = socket(AF_INET,SOCK_STREAM,0); UDP:sockfd =socket(AF_INET, SOCK_DGRAM,0);,socket()调用,“协议” 与“family” 及“type”域的可能组合,在服务器上运行,给socket指定一个众所周知的 (well-known) 端口地址 int bind (
9、int sockfd, const struct sockaddr *myaddr, socklen_t addrlen),bind() 调用,如果调用成功,则返回值为0,如果调用失败返回值为-1,并设定相应的错误代码errno。最常见的错误是该端口已经被其他程序绑定。 需要注意的一点:在Linux系统中,1024以下的端口(即众所周知的端口)只有拥有root权限的程序才能绑定,bind() 调用,Bind()系统调用主要用处: A)服务员向系统注册它的众所周知的地址,它告诉系统:“这是我的地址(服务),所有以这个地址接收的报文都交给我,由我来服务。”面向连接和无连接的服务员在接受顾客的请求之
10、前都必须做这一步。 B)顾客可为它自己注册一个特定的地址,以便通信的对方(服务员)可以用这个有效的地址送回响应,这就像在信封上要写明回信地址的道理一样。,开始监听已经绑定的端口 需要在此前调用bind()函数,否则由系统指定一个随机的端口 int listen(int sockfd, int queue_length); 接收队列 一个新的Client的连接请求先被放在接收队列中,等待Server程序调用accept函数接受该连接请求 queue_length用于指定接收队列的长度,也就是在Server程序调用accept函数之前最大允许进入的连接请求数,多余的连接请求将被拒绝,典型取值为5,
11、listen() 调用,操作系统,Web 服务器,服务器初始化,建立与服务器的连接 int connect (int sockfd, const struct sockaddr *servaddr, socklen_t addrlen) servaddr是事先填写好的结构,用于指定所要连接的服务器的地址(Server的IP地址和端口号)。,connect() 调用,OS,1. socket(),Web 服务器,2. bind(80),3. listen(),80,Listen queue,客户,connect(),Request from (IP, port),建立与服务器的连接,操作系统,W
12、eb 服务器,80,Listen 队列,客户1,客户3,客户2,客户请求在listen队列中获取先进先出服务(排队),服务器忙,accept(),accept()函数用于响应客户的连接请求,建立与客户端的连接 产生一个新的socket描述符来描述该连接 这个连接用来与发起该连接请求的Client交换信息 int accept(int sockfd,struct sockaddr *addr,int addrlen); addr将在函数调用后被填入连接对方(客户端)的地址信息,如对方的IP、端口等。 accept缺省是阻塞函数,如果队列中没有连接请求等待,那么就会使调用方阻塞,直到有一个连接请求
13、到达。,操作系统,Web 服务器,80,Listen 队列,客户 1,客户3,客户2,客户请求在listen队列中夺取先进先出服务,accept(),已连接的 socket,accept() 调用,accept()的使用,include #include #include #define MYPORT 80 /* the port users will be connecting to */ #define BACKLOG 5 /* how many pending connections queue will hold */ main() int sockfd, new_fd; /* lis
14、ten on sock_fd, new connection on new_fd */ struct sockaddr_in my_addr; /* my address information */ struct sockaddr_in their_addr; /* connectors address information */ int sin_size; sockfd = socket(AF_INET, SOCK_STREAM, 0); /* do some error checking! */,accept(),my_addr.sin_family = AF_INET; /* hos
15、t byte order */ my_addr.sin_port = htons(MYPORT); /* short, network byte order */ my_addr.sin_addr.s_addr = INADDR_ANY; /* auto-fill with my IP */ bzero( ,服务器都可工作在两种不同的方式: 循环方式(iterative mode)在计算机中一次只运行一个服务器进程。当有多个客户进程请求服务时,服务器进程就按请求的先后顺序依次做出响应。 并发方式(concurrent)在计算机中同时运行多个服务器进程,每一个服务器进程对某个特定的客户进程做出响
16、应。,服务器的两种工作方式,循环型服务员代码,int sockfd,newsockfd; if (sockfd=socket()0) err_sys(“socket error”); if (bind(sockfd,)0) err_sys(“bind error”); if (listen(sockfd,5)0) err_sys(“listen error”); for ( ; ; ) newsockfd=accept(sockfd,);/* blocks */ if (newsockfd0) err_sys(“accept error”); doit(newsockfd);/* proces
17、s the request */ close(newsockfd); ,并发型服务员代码,int sockfd,newsockfd; if (sockfd=socket()0) err_sys(“socket error”); if (bind(sockfd,)0) err_sys(“bind error”); if (listen(sockfd,5)0) err_sys(“listen error”); for ( ; ; ) newsockfd=accept(sockfd,);/* blocks */ if (newsockfd0) err_sys(“accept error”); if
18、(fork()=0)/* child */ close(sockfd); doit(newsockfd);/* process the request */ exit(0); close(newsockfd);/* parent */ ,发送和接收,在完成了上述的初始化工作后,就可以开始传输数据了。 面向连接的发送和接收 : send() and recv() 无连接协议的发送和接收:sendto()和recvfrom(),recv,用于TCP协议中接收信息 int recv(int sockfd, void *buf, int len, int flags); Buf:指向容纳接收信息的缓冲
19、区的指针 Len:接收缓冲区的大小 Flags:接收标志(其含义将在后面介绍) 函数返回实际接收到的字节数,返回-1表示出错 recv缺省是阻塞函数,直到接收到信息或出错才返回,send,用于TCP协议中发送信息 int send(int sockfd, const void *msg, int len, int flags); Msg:指向待发送信息的指针 Len:待发送的字节数 Flags:发送标志(其含义将在后面介绍) 函数返回已发送的字节数,返回-1表示出错 send缺省是阻塞函数,直到发送完毕或出错 注意:如果函数返回值与参数len不相等,则剩余的未发送信息需要再次发送,recvfr
20、om,用于UDP协议中接收信息 int recvfrom(int sockfd,void *buf,int len,unsigned int flags struct sockaddr *from, int *fromlen); Buf:指向容纳接收信息的缓冲区的指针 Len:缓冲区的大小 Flags:接收标志(其含义将在后面介绍) From:指明接收数据的来源 Fromlen:地址长度 函数返回实际接收的字节数,返回-1表示出错 recvfrom是阻塞函数,直到接收到信息或出错,sendto,用于UDP协议中发送信息 int sendto(int sockfd, const void *ms
21、g, int len, unsigned int flags, const struct sockaddr *to, int tolen); Buf:指向容纳发送报文的缓冲区的指针 Len:缓冲区的大小 Flags:发送标志 To:指明发送数据的目的地 tolen :地址长度 函数返回已发送的字节数,返回-1表示出错 sendto缺省是阻塞函数,直到发送完毕或出错 注意:如果函数返回值与参数len不相等,则剩余的未发送信息需要再次发送,send, sendto, recv, recvfrom函数调用的参数:flags,Flags一般情况下设置为0。但可以选择下列设置 MSG_DONTROUTE
22、 对send, sendto有效 表示不使用路由(一般不使用) MSG_PEEK 对recv, recvfrom有效 表示读出网络数据后不清除已读的数据 MSG_OOB 对发送接收都有效 表示读/写带外数据(out-of-band data),close,关闭特定的socket连接 调用函数:int close(int sockfd); 关闭连接将中断对该socket的读写操作。 关闭用于listen()函数的socket将禁止其他Client的连接请求,shutdown,Shutdown()函数可以单方面的中断连接,即禁止某个方向的信息传递。 函数调用 int shutdown(int so
23、ckfd, int how); 参数how: 0 - 禁止接收信息 1 - 禁止发送信息 2 - 接收和发送都被禁止,与close()函数效果相同 返回0表示调用成功,返回-1表示出错,select,应用于多路同步I/O模式,实现非阻塞的同步I/O int select(int numfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); numfds是要多路选择的socket的最大值 其中readfds, writefds, exceptfds都是socket事件集合,分别代表有
24、数据可读、有数据要写、发生异常的socket集合。 timeout是select的时间限制 返回值:在socket集合中准备好的socket个数,socket集合,集合变量类型:fd_set 集合变量运算宏: FD_ZERO(*set)清空socket集合 FD_SET(s, *set)将s加入socket集合 FD_CLR(s, *set)从socket集合去掉s FD_ISSET(s, *set)判断s是否在socket集合中 常数FD_SETSIZE:集合元素的最多个数,Select应用举例,fd_set rset;/* 可读的socket集合 */ FD_ZERO( /* maxfd是
25、已知的最大的socket */ /* 只考虑数据可读事件 */ if (FD_ISSET(sockfd, - 其中,参数peer是一个指向struct sockaddr或者struct sockaddr_in的指针。 如果执行成功,我们就得到了对方的地址和端口号,然后用inet_ntoa()和gethostbyaddr()来得到对方更多的信息。,其他基本的系统调用,getsockname 该系统调用返回和一个管套相联系的本地名字 - #include #include int getsockname(int sockfd, struct sockaddr *addr, int *addrlen
26、); - addr用来存放返回的本地地址;addrlen存放的是返回的地址的长度。,其他基本的系统调用,系统调用 gethostname() - - #include int gethostname(char *hostname, size_t size); - - hostname是一个存放主机名字(域名)的字符数组 返回的hostname可以作为gethostbyname()的参数,调用该系统调用,这样又可以得到自己的IP地址了。,其他基本的系统调用,字节排序 在字节顺序不一致时可以用下列的4中函数来进行转换。 #include #include u_long htonl(u_long h
27、ostlong);/* 主机网络转换,长整数 */ u_short htons(u_long hostlong);/* 主机网络转换,短整数 */ u_long ntohl(u_long hostlong);/* 网络主机转换,长整数 */ u_chort ntohs(u_long hostlong);/* 网络主机转换,短整数 */ 这些函数是为internet协议集而设计的,XNS协议集采用的字节顺序与internet相同,故可以借用。值得注意的是,这里的长整数为32位,短整数为16位。,其他基本的系统调用,字节操作 Bcopy(char *src,char *dest,int nbyte
28、s); 字符串拷贝 Bzero(char *dest,int nbytes); 把指定数量的空字节写入指定的目的地址。 Int bcmp(char *ptr1,char *ptr2,int nbytes); 对任意两个字符串进行比较。 返回值(与标准I/O函数strcmp的返回值不同): 0-相同 非零-不相同。,其他基本的系统调用,IP地址格式转换 下列两个函数用于在Internet的用小数点分隔的十进制IP地址与32比特IP地址之间进行转换。 #include #include #include unsigned long inet_addr (const char *cp); inet_addr将一个点分十进制IP地址字符串转换成32位数字表示的IP地址 char* inet_ntoa (struct in_addr in); inet_ntoa将一个32位数字表示的IP地址转换成点分十进制IP地址字符串,其他基本的系统调
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 课题开题报告:湖北省民办本科高校职业生涯教育培训体系研究
- 课题开题报告:湖北省1+X证书制度试点推进与实施研究
- 课题开题报告:国家海洋战略教育体系研究
- 课题开题报告:孤独症群体全生命周期培养体系构建和标准研究
- T-SHV2X 3-2025 车联网服务平台风险评估实施指南
- 2025年家用音视频设备合作协议书
- 恐龙脚印施工方案
- 护理三基知识培训课件
- 代可可脂巧克力制品企业数字化转型与智慧升级战略研究报告
- 工具书籍专门零售企业数字化转型与智慧升级战略研究报告
- DB12-595-2015医院安全防范系统技术规范
- 五年级下册英语课件-Unit 2 My favourite season B Let's learn 人教PEP版(共15张PPT)
- GB∕T 7260.40-2020 不间断电源系统 UPS 第4部分:环境 要求及报告
- 高边坡施工危险源辨识及分析
- 水厂项目基于BIM技术全生命周期解决方案-城市智慧水务讲座课件
- 幼儿园绘本:《闪闪的红星》 红色故事
- 三年级学而思奥数讲义.doc
- 刘姥姥进大观园课本剧剧本3篇
- 产品承认书客(精)
- 长方体和正方体的认识(动画)(课堂PPT)
- 投标人基本情况一览表格
评论
0/150
提交评论