第10单元 网络IPC套接字_第1页
第10单元 网络IPC套接字_第2页
第10单元 网络IPC套接字_第3页
第10单元 网络IPC套接字_第4页
第10单元 网络IPC套接字_第5页
已阅读5页,还剩46页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、Linux系统编程第10单元网络IPC套接字2第10单元网络IPC套接字n网络编程基本概念n10.1套接字描述符n10.2寻址n10.3BSDSocket网络通信编程n10.4面向连接的网络通信实例n10.5无连接的网络通信实例n10.6基于并发服务器的网络数据传输OSI模型及TCP/IP协议模式3TCP/IP体系结构及各层协议45IP地址和端口nIP地址:标识主机,IPv432位,IPv6128位n端口:标识某主机上的某个应用进程,16位无符号整数。一台主机可以通过多个端口提供多个服务分类:n公认口(well-knownport):系统保留,0-1023n动态端口:进程使用需申请。n在全局标

2、识一个应用进程协议,本地IP,本地端口号n标识一个完整的网间通信协议,本地IP,本地端口号,远地IP,远地端口号网络数据包封包与拆包过程6字节顺序n大于一个字节的类型的数据在内存中的存放顺序Little-Endiann小端,低位字节在内存低地址端,高位字节在内存高地址端。n处理器架构:Intelx86Big-Endiann大端,高位字节在内存低地址端,低位字节在内存高地址端。n处理器架构:SunSPARC,JavaVirtualMachine7主机/网络字节顺序n主机字节顺序两种都有可能,所以不同字节顺序的主机之间发送信息容易出错。在此特指IP地址和端口n网络字节顺序TCP/IP协议使用Big

3、-Endiann转换函数。主机to网络:htonlhtons网络to主机:ntohlntohsl:32位,s:16位参数为原数,返回值为转换后的数。8套接字类型n流式套接字基于TCP协议,面向连接,可靠n数据报套接字基于UDP协议,无连接,不可靠n原始套接字超级用户使用,对网络下层通信协议进行访问9TCP套接字通信过程1011TCP套接字通信过程n服务器先启动调用socket函数创建一个套接字s。调用bind函数将s绑定一个地址和端口号。调用listen函数使s成为一个监听套接字。调用accept阻塞等待接收客户端请求,建立与某客户端的连接套接字ns。通过ns,调用读写函数处理某客户端请求终止

4、连接ns。n客户端调用socket函数创建一个套接字s1。填写服务器的地址和端口号。调用connect函数与服务器建立连接。调用读写函数与服务器发送或接收数据。终止连接s1。UDP套接字通信过程13UDP套接字通信过程n服务器调用socket函数创建一个套接字s。调用bind函数将s绑定一个地址和端口号。等待并接收客户端请求。调用读写函数处理客户端请求关闭套接字。n客户端调用socket函数创建一个套接字s1。调用读写函数发送或接收数据给服务器。关闭套接字。14准备工作n分别创建文件makefile,server.c和client.c。nserver.c和client.c先写出main函数结构

5、。nmakefile文件内容见右:n测试make命令和makeclean命令all:serverclientserver:server.cgcc$-o$client:client.cgcc$-o$clean:rmserverclient-f15n#includenintsocket(intfamily,inttype,intprotocol);n功能:创建套接字。n参数:family:程序所在主机采用的通信协议,AF_INET(IPv4),AF_INET6(IPv6)。type:要建立的套接字类型:SOCK_STREAM(流式),SOCK_DGRAM(数据报),SOCK_RAW(原始)。pro

6、tocol::一般为0,除原始套接字外。n返回值:成功:套接字描述符,失败:1。socket16server.csocketn#include-n/变量定义部分intsockfd;-n/代码部分sockfd=socket(AF_INET,SOCK_STREAM,0);if(sockfd=-1) perror(socket);exit(1);17bind#includeintbind(intsockfd,conststructsockaddr*addr,socklen_lenlen)n该函数指明套接字将使用本地的哪一个协议端口进行数据传送(IP地址和端口号),注意:协议地址addr是通用地址。n

7、参数:sockfd:由socket()调用返回的套接字描述符。addr:本地套接字地址,通用地址结构(第三章)len:本地套接字地址长度,即addr的长度。n返回值:成功:返回0,失败:1并置errno。套接字地址结构n通用地址结构structsockaddr unsignedshortsa_family;/协议族charsa_data14;/协议地址;nTCP/IP协议簇地址结构structsockaddr_inshortsin_family; /协议族如AF_INETunsignedshortsin_port; /端口号structin_addrsin_addr;/网络地址charsin_

8、zero8;/填充0;structin_addrunsignedlongs_addr;18套接字地址结构n套接字相关函数的参数一般都用通用地址结构类型structsockaddr指针。n具体在调用套接字函数时,可使用TCP/IP协议簇地址结构structsockaddr_in定义变量,将地址强制转换成structsockaddr类型指针。n举例:structsockaddr_inmy_addr;my_addr.sin_family=AF_INET;my_addr.sin_port=htons(1500);my_addr.sin_addr.s_addr=inet_addr(“192.168.1.

9、80”);bzero(&(my_addr.sin_zero),8);bind(sockfd,(structsockaddr*)my_addr,sizeof(structsockaddr);1920#include-structsockaddr_inserver;intport=1234,rt,opt=SO_REUSEADDR;-/避免出现地址已经使用的错误setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt);bzero(&server,sizeof(server);server.sin_family=AF_

10、INET;/familyserver.sin_addr.s_addr=inet_addr(“127.0.0.1”);/IPserver.sin_port=htons(port);/portrt=bind(sockfd,(structsockaddr*)&server,sizeof(server);if(rt=-1)perror(bind);exit(1);21listennintlisten(intsockfd,intbacklog);n服务器在已绑定的端口上开始监听,将sockfd转换成为监听套接字。n参数:sockfd:由socket()调用返回的套接字描述符。backlog:请求

11、队列大小,已经收到连接请求但还没accept的队列。n返回值:成功:返回0,失败:返回-1。22listen使用intbacklog=5;-rt=listen(sockfd,backlog);if(rt=-1)perror(listen);exit(1);23acceptnintaccept(intsockfd,structsockaddr*client,int*addrlen);n从连接请求队列中接受一个连接,sockfd作为监听套接字继续监听。n参数:client:请求连接主机的地址。addrlen:请求连接主机地址长度。可都置为NULL。n返回值:成功:连接套接字描述符。失败:1。n服务

12、器可以通过参数client来得到客户的地址和端口号。24accept说明naccept函数由TCP服务器调用;从已完成连接队列头返回下一个已完成连接;如果该队列空,则进程进入睡眠状态。n函数返回的套接字为已连接套接字,应与监听套接字区分开来。新产生的连接套接字用来与客户端进行数据通信原来的监听套接字用来监听其他客户端的连接请求25server.cacceptintconnfd;structsockaddr_inclient;intaddrlen;-addrlen=sizeof(client);connfd=accept(sockfd,(structsockaddr*)&client,&

13、amp;addrlen);if(connfd=-1)perror(accept);exit(1);数据传输函数nreadwrite第一个参数为连接套接字描述符nrecvsend比readwrite多一个参数,代表选项2627recv()nintrecv(intsockfd,void*buf,intlen,unsignedintflags);n接收数据,比read多了一个flagsn参数:flags:传输控制标志。n0:同read()nMSG_PEEK:只查看数据而不读出数据,后续读操作仍然能读出所查看的该数据;nMSG_OOB:忽略常规数据,只读带外(紧急)数据。nMSG_WAITALL:等希

14、望接收的数据字节到达后返回,否则阻塞等待。返回条件:1读到指定字节个数的数据,2读到文件结束符,3被信号中断,发生错误。28send()nintsend(intsockfd,void*buf,intlen,intflags);n发送数据,比write多了一个flagsn参数:flags:传输控制标志。n0:同write()nMSG_OOB:发送带外(紧急)数据。nMSG_DONTROUTE:忽略底层协议的路由设置,只能将数据发送给与发送机处在同一个网络中的机器上。29server.csendcharsendbuf100;-/输出客户端地址,字符串形式printf(client:%sn,inet

15、_ntoa(client.sin_addr);/向客户端发送欢迎信息sprintf(sendbuf,hello,welcome!);rt=send(connfd,sendbuf,strlen(sendbuf),0);if(rt=-1)perror(send);30closenintclose(intsockfd);n套接字描述符将不再可用,系统会将套接字发送缓冲区的数据发送出去,直到TCP连接终止。n返回值:成功返回0;失败返回1。nserver.c结束:close(connfd);close(sockfd);31connect()nintconnect(intsockfd,structsoc

16、kaddr*addr,intaddrlen);n客户端与服务器建立连接,激发TCP的三路握手过程。n参数:addr:目的主机地址,即服务器的地址。n返回值:成功:返回0;失败:返回1。32nconnect激发TCP的三路握手过程;仅在成功或出错返回;错误有以下几种情况:ETIMEDOUT:如果一段时间内客户没有收到SYN分节的响应(定时期间可能需要重发若干次SYN)。ECONNREFUSED:如果对客户的SYN的响应是RST,则表明该服务器主机在指定的端口上没有进程在等待与之相连。connect说明33编写client.c-提示命令行参数intmain(intargc,char*argv)if

17、(argc!=2)printf(Usage:%sn,argv0);exit(1);34编写client.c-socketintfd;-fd=socket(AF_INET,SOCK_STREAM,0);if(fd=-1)perror(socket);exit(1);35编写client.c-connect#definePORT1234/与服务器同-structsockaddr_inserver;intrt;-bzero(&server,sizeof(server);server.sin_family=AF_INET;server.sin_port=htons(PORT);server.s

18、in_addr.s_addr=inet_addr(argv1);rt=connect(fd,(structsockaddr*)&server,sizeof(structsockaddr);if(rt=-1)perror(connect);exit(1);36编写client.c-数据传输并显示charbuf100;intnumbytes;-numbytes=recv(fd,buf,sizeof(buf),0);if(numbytes=-1)perror(recv);exit(1);bufnumbytes=0;printf(ServerMessage:%sn,buf);37编写clien

19、t.c-关闭close(fd);38执行结果n编译:maken运行:服务器:./server客户端:./client127.0.0.1n运行结果服务器:client:127.0.0.1客户端:ServerMessage:hello,welcome!服务器程序改进n目前的服务器处理完一个客户请求后即退出。n正常情况下,服务器是不退出还可以接收下一个客户端请求的。n在connfd=accept(.);前加“while(1)”n在close(connfd);后加“”n可以将服务器变成重复性服务器,处理完客户请求后服务器不退出,继续处理下一个客户请求。n服务器同时处理多个客户请求,称为并发服务器。n并

20、发机制:多进程、多线程、I/O多路复用39TCP的缓冲区n每个TCP套接口有一个发送缓冲区,当应用进程调用write往套接口写数据时,内核从应用进程缓冲区中拷贝所有数据到套接口的发送缓冲区,如果套接口发送缓冲区容不下应用程序的所有数据,或者是应用进程的缓冲区大于套接口的发送缓冲区,或者是套接口的发送缓冲区中有别的数据,此时应用进程将被挂起。内核将不从write返回。直到应用进程缓冲区中的所有数据都拷贝到套接口发送缓冲区。nwrite调用成功返回仅仅表示可以重新使用应用进程缓冲区,并不是告诉进程对方收到数据。TCP发给对方的数据,对方在收到数据时必须给予确认,只有在收到对方的确认时,本方TCP才

21、会把TCP发送缓冲区中的数据删除。40TCP的缓冲区41套接字发送缓冲区套接字接收缓冲区进程的应用缓冲区进程的应用缓冲区InternetTCP协议UDP的缓冲区nUDP因为是不可靠连接,不必保存应用进程的数据拷贝,应用进程中的数据在沿协议栈向下传递时,以某种形式拷贝到内核缓冲区,当数据链路层把数据传出后就把内核缓冲区中数据拷贝删除。因此它不需要一个发送缓冲区。n写UDP套接口的write返回表示应用程序的数据或数据分片已经进入链路层的输出队列,如果输出队列没有足够的空间存放数据,将返回错误ENOBUFS.42UDP的缓冲区43UDP数据报UDP数据报UDP数据报读函数recvfrom( )UD

22、P套接字接收缓冲区UDP套接字通信过程45UDP套接字编程sendtonsendtointsendto(intsockfd,void*buf,intlen,unsignedintflags,structsockaddr*to,inttolen);发送数据,直接将数据复制到系统缓冲区。参数:nto:数据接收方地址。ntolen:数据接收方地址长度。返回值:0:实际发送的数据字节数0:发送空数据报。-1:错误。46UDP套接字编程recvfromnrecvfromintrecvfrom(intsockfd,void*buf,intlen,unsignedintflags,structsockaddr*from,int*fromlen);接收数据,阻塞方式读接收缓冲区队列,接收缓冲区满则丢弃并不通知发送方。参数:nfrom:数据发送方源地址。nfromlen:数据发送方地址长度。n如果对发送方不感兴趣,可都置为NULL。返回值:0:接收的字节数,=0:无数据-1:错误477.6.1域名解析n域名:机构或者个人在互联网上注册的名称,是互联网上企业或机构间相互联络的网络地址。代替IP地址国际顶级域名nICANN负责管理,类别、地理、新国内顶级域名nCNNIC负责管理n域名解析通过DNS服务器将

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论