LINUX C编程网络编程.ppt_第1页
LINUX C编程网络编程.ppt_第2页
LINUX C编程网络编程.ppt_第3页
LINUX C编程网络编程.ppt_第4页
LINUX C编程网络编程.ppt_第5页
已阅读5页,还剩21页未读 继续免费阅读

下载本文档

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

文档简介

LINUXC编程,套接字与网络编程,TCP/IP协议简介Socket编程,专门用于为用户提供应用服务(ftp,telnet,Smtp.),TCP/IP参考模型,应用层,传输层,互联网层,网络接口层,管理连接中端到端通信的协议层,定义了TCP(传输控制协议),UDP(用户数据报协议),并提出了port的概念。,主要实现将上层传下来的数据包封装成底层物理网络支持的数据格式,并转化成真正的电气信号在物理网络上传输。,最重要的概念IP协议,即对IP地址进行了分组。,网络协议中一些术语,面向连接(Connection-oriented)的协议有两个端点,在通信之前必须建立连接。协议提供了顺序性(sequencing),保证数据按照发送的顺序到达目的地。协议提供了错误控制(errorcontrol),可以自动丢弃损坏的消息,然后安排重新发送数据。流(stream)协议仅仅识别字节边界,也就是说一个字节的序列可以被分割成片,然后发送出去,但是接收到的数据仍然是原数据。基于包(Packet-based)协议处理数据包,保持包边界向接收者发送整个包。,UDP(数据报协议datagram)协议是基于包协议,TCP协议是基于流协议的,不仅提供顺序性,而且提供了错误控制。,Linux中的TCP/IP网络结构,用户进程,套接字接口,网络协议,网络设备,是进程与网络协议之间的接口中。在Linux中socket属于文件系统的一部分,网络通信可以看成对文件的读取。,在一个通信连接中的两端通信程序各自有一个套接字来描述自己那一端。,Socket编程,套接字与文件描述字相同点:像文件描述字一样,套接字也使用read,write来读写数据。不同点:套接字除了有一个地址以外,还包含3个属性域、类型和协议。,Socket编程相关的数据结构1,Structsockaddr:保存着套接字的地址信息StructsockaddrUnsignedshortsa_family;/地址族Charsa_data14;/套接字实际的地址数据(目的地址及端口),每种协议都有自己的网络地址的定义,套接字API必须对这些不同的地址定义进行抽象。,Socket编程,Socket编程相关的数据结构1,协议和地址族,Internet通信域套接字地址结构sockaddr_instructsockaddr_inshortintsin_family;/地址族unsignedshortintsin_port;/端口号structin_addrsin_addr;/IP地址charsin_zero8;/填充0以保持与structsockaddr同样大小,这样一个指向sockaddr_in数据结构的指针可以强行转换为一个指向数据结构sockaddr的指针。/端口号以及Internet地址使用的是网络字节顺序,需要通过特殊函数进行转换,Socket编程,Socket编程相关的数据结构2,Socket编程,网络字节顺序,TCP/IP网络通常是异构的,它包含大量不同种类的计算机及体系结构。在体系结构上最大的区别就是存储数据的方式。常见的方式有两种,大尾端(把最高位的字节存放在最低的硬件地址上)和小尾端(反之)。TCP/IP协议使用大尾端,而所有的intel和intel兼容的处理器都采用小尾端字节存储顺序。因此在网络上传输多字节数据的顺序被称为网络字节顺序。,几个字节顺序转换函数:Htons:”HostToNetworkShort”,主机地址-网络字节顺序Htonl:”HostToNetworkLong”,主机地址-网络字节顺序(长型),此长型非C语言中的long,详见函数原型。ntohs:”NetworkToHostShort”,网络字节顺序-主机地址ntohl:”NetworkToHostlong”,网络字节顺序-主机地址(长型),获取服务器和客户端主机信息,#includeStructhostent*gethostbyname(constchar*hostname);/将机器名()转换为一个hostent的结构指针,在这个结构里保存域名的地址信息。Structhostent*gethostbyaddr(constchar*addr,intlen,inttype);将一个32位的IP地址(C0A80001)转换为一个hostent的结构指针,在这个结构里保存域名的地址信息。,Ip地址和域名的转换,Structhostentchar*h_name;/主机的正式名字(域名)char*h_aliases;/主机的别名inth_addrtype;/主机的地址类型(如AF_INET)inth_lengh;/主机的地址长度,对于IPV4为说是4个字节其32位char*h_addr_list;/主机的IP地址列表#defineh_addrh_addr_list0/主机的第一个IP地址,获取服务器和客户端主机信息,#include#includeIntinet_aton(constchar*cp,structin_addr*inp)char*inet_ntoa(structin_addrin)/网络上的IP地址都是由“点分十进制”(“”)方式表示,在structin_addr结构中采用的是32位的IP地址,“”实际表示为32位的IP地址应该为C0A80100。a代表”ascii”,n代表”network”。Inet_aton()将a.b.c.d的IP转换为32位的IP地址,并存储在inp指针所指向的地址里;Inet_ntoa()将32位的IP地址转换为”a.b.c.d”的字符串格式。,字符串的IP地址与32位的IP地址的转换,获取服务器和客户端主机信息,字符串的IP地址与32位的IP地址的转换,获取服务器和客户端主机信息,#includestructhostent*gethostbyname(constchar*hostname);域名-IP转换structhostent*gethostbyaddr(constchar*hostname);IP域名转换,获取主机信息的函数,Socket编程,基于TCP,即面向连接的通信数据流,#include#includeintsocket(intdomain,inttype,intprotocol)函数说明:创建一个套接字描述符,如果失败返回-1.domain为地址族AF_XXX,type为套接字类型,SOCK_STREAM(TCP),SOCK_DGRAM(UDP),SOCK_RAW(IP、ICMP);protocol指定协议0为自动选择。,(第一步)创建套接字以获得文件描述符,Socket编程(采用客户端/服务器端模工作),#include#includeintbind(intsockfd,structsockaddr*my_addr,intaddrlen);函数说明:成功返回0,如果失败返回-1sockfd:由socket()调用返回的文件描述符myaddr:指向sockaddr的指针,由于系统兼容性问题,一般使用structsockaddr_in代替。addrlen:sockaddr结构的长度,Socket编程步骤,(第二步)建立连接,将套接字与本地计算机的地址绑定在一起,Socket编程,#include#include#include#defineMYPORT3333/最好选择1024以后的端口Main()Intsockfd;Structsockaddr_inmy_addr;/通常情况下使用sockaddr_in结构Sockfd=socket(AF_INET,SOCKET_STREAM,0);my_addr.sin_family=AF_INET;my_addr.sin_port=htons(MYPORT);/或者设置为零也可,内核会自动分配一个未使用的端口My_addr.sin_addr.s_addr=inet_addr(“25”);/写法二My_addr.sin_addr.s_addr=htonl(INADDR_ANY);非指定地址被包含在常量INADDR_ANY中Bzero(.,将套接字与本地计算机的某个端口绑定在一起(示范如何使用bind),intopt=1;setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,在套接字被绑定到地址后,进程通过调用listen(),来告诉系统它愿意让其它进程与该套接字建立连接。,intlisten(intsockfd,intbacklog);sockfd:bind()后的文件描述符。Backlog:等待联机队列的大小,等待中而未被accept()的联机请求被放在队列,当队列满了就无法再接受联机请求,client会收到connectionrefused的错误。执行成功返回0,失败为1。,Socket编程步骤,(第三步)等待client联机请求,intaccept(intsockfd,structsockaddr*addr,int*addrlen)Sockfd:是listen后的文件描述符Addr:将被client的ipaddress填充Addrlen:将被client的ipaddress的长度填充成功则返回client的socket文件描述符,之后的数据传输就可以使用新的文件描述符。,Socket编程步骤,(第四步)接受client联机请求,连接并不是立即建立进来的,必须通过accept()系统调用接收连接请求,新的试图连接到已监听地址的连接请求称为未决的连接,这个连接一直等待直到被accept()为止。,Socket编程,客户端步骤,intconnect(intsockfd,structsockaddr*serv_addr,intaddrlen);sockfd:socket返回的文件描述符serv_addr:指向structsockaddr的指针,保存服务器端的连接信息Addren:可以用sizeof(structsockaddr)设置成功返回0,出错则返回-1,第一步与server端程序相同,第二步可直接使用connect与服务器连接,用于建立连接后完成发送与接收数据的系统调用(数据流套接字),Send()和recv()函数,#includeintsend(intsockfd,constvoid*msg,intlen,intflags)Sockfd:希望进行数据传递的套接字的文件描述符Msg:指向发送数据的指针Len:希望发送的数据的字节长度Flags:通常设置为0成开则返回实际发送字节的长度,出错则返回-1,intrecv(intsockfd,void*buf,intlen,unsignedintflags)Buf:保存读入信息的地址Len:表示接收buf的最大长度,可以使用close(intsockfd)和shutdown(intsock,inthow)来关闭连接的套接字文件描述符,Shutdown中的how参数含义如下:0:代表断开远程接收1:代表断开远程发送2:代表断开远程接收和发送,listenfd=socket(.);bind(listenfd,.);listen(listenfd,.);while(1)connfd=accept(listenfd,.);n=fork();if(n=-1)perror(calltofork);exit(1);elseif(n=0)close(listenfd);while(1)read(connfd,.);write(connfd,.);close(connfd);exit(0);elseclose(connfd);,使用fork并发处理多个client的请求,基于UDP的c/s模式,用于无连接发送与接收数据的系统调用(用于数据报套接字),Sendto()和recvfrom()函数,#includeintsendto(intsockfd,constvoid*msg,intlen,unsignedintflags,Conststructsockaddr*to,inttolen)除最后两个参数之外

温馨提示

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

评论

0/150

提交评论