您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 公司方案 > 第2章 UnixLinux下的网络程序设计
第1页第二章Unix/Linux下的网络程序设计第2页22Unix平台上的网络攻防程序设计2.1套接字编程的基础2.2基于TCP协议的套接字编程2.2基于UDP协议的套接字编程2.3rawsocket2.4Libpcap2.5libnet第3页3导入网络程序是通过计算机网络与其它程序通信的程序,它和普通的程序的最大的区别是网络程序是由两个部分组成的:客户端和服务器端,二者通过网络相互通信。大多数系统提供预先编译好的网络程序,如web程序、FTP和Telnet。服务器程序先启动,在一个端口上监听,等待客户端的程序运行并建立连接。第4页42.1套接字编程的基础套接字,也称Berkeley套接字,因为它源自BerkeleyUnix。网络程序通过socket和其它几个函数的调用完成网络的连接以及数据的交流。套接字是一个整型数,是一个用于通信的文件描述符,可以象普通的文件描述符一样来操作,向该描述符的读写操作实现网络之间的数据交流。网络编程所需的知识和概念在很大程度上并不依赖于操作系统,他们都基于TCP/IP协议族,因此绝大多数函数在Windows等操作系统上仍可使用第5页5套接字地址结构#includesys/socket.htypedefuint32_tin_addr_t;structin_addr{in_addr_taddr;}typedefuint16_tin_port_t;structsockaddr_in{uint_8sin_len;/*结构长度,uint_8是8位的无符号整数类型*/sa_family_tsin_family;/*AF_UNIXAF_INETAF_INET6AF_IPXAF_APPLETALK*//*套接字地址族*/int_port_tsin_port;/*16位的TCP或UDP端口号*/structin_addrsin_addr;/*32位的IPv4地址*/charsin_zero[8];/*暂不用,总置为0*/}第6页6通用套接字地址结构如下:structsockaddr{unit8_tsa_len;sa_family_tsa_family;charsa_data[14];/*协议相关的地址*/}第7页7字节排序对一个16位整数,它由2个字节组成,内存中存储这两个字节有两种方法:小端(little-endian)字节序:将低位存储在低字节位;大端(big-endian)字节序:将高位存储在低字节位。把主机系统所用的字节序称为主机字节序(hostbyteorder)网络协议所用的字节序称为网络字节序(networkbyteorder)低0x120x340x340x12高大端小端第8页8Unix系统提供了一组函数,用于完成主机字节序和网络字节序之间的转换:#includenetinet/in.huint16_thtons(unit16_th)uint32_thtonl(unit32_th)uint16_tntohs(unit16_tn)uint32_tntohl(unit32_tn)当使用这些函数时,不关心主机字节序和网络字节序的真实值。所做的只是调用适当的函数来对给定的值进行主机字节序与网络字节序间的转换。第9页9地址转换函数人们熟悉的是点分十进制的IP地址,而上面的套接字地址结构中使用无符号整数存储IP地址。Unix系统提供了一组函数,用于在ASCII字符串地址与网络字节序的二进制值间转换地址。#includearpa/inet.hintinet_aton(constchar*strptr,structin_addr*addrptr);in_addr_tinet_addr(constchar*strptr);char*inet_ntoa(structin_addrinaddr)intinet_pton(intfamily,constchar*strptr,void*addrptr);constchar*inet_ntop(intfamily,constvoid*addrptr,char*strptr,size_tlen);第10页10基于TCP套接字的网络编程创建套接字函数intsocket(intfamily,inttype,intprotocol)type:SOCK_STREAM,SOCK_DGRAM,SOCK_RAW绑定函数intbind(intsockfd,structsockaddr*my_addr,intaddrlen)监听函数intlisten(intsockfd,intbacklog):backlog请求排队队列长度接受函数intaccept(intsockfd,structsockaddr*cliaddr,int*addrlen)监听套接字(一般一个服务器只有一个,且与服务一起存在);已连接套接字(接受一个客户端connect请求即生成一个连接)第11页11基于TCP套接字的网络编程连接函数connectintconnect(intsockfd,structsockaddr*serv_addr,intaddrlen)调用connect之前,客户端可以不调用bind,由内核自动选择源IP地址和临时端口Connect函数激发TCP三次握手,可能返回的错误包括:(1)ETIMEOUT:TCP客户没有收到服务器对SYN包的响应;(2)ECONNREFUSED:服务器响应RST,表明服务器在指定端口上没有进程在等待连接;(3)EHOSTUNREACH/ENETUNREACH:客户端发出的SYN包在中间路由器上引发一个目的不可达ICMP错误;第12页12基于TCP套接字的网络编程连接中止函数closeintclose(intsockfd)做“已关闭”标记,不再读写套接字,但套接字继续发完已排队待发的数据;连接关闭函数shutdownintshutdown(intsockfd,inthowto)howto=0:关闭读通道,可以继续写数据;howto=1:关闭写通道,可以继续读数据;howto=2:关闭读写通道,类似于close;写函数writessize_twrite(intfd,constvoid*buf,size_tnbytes)成功时返回.0;失败时返回-1,并设errno变量:(1)EINTR:终端错误;(2)EPIPE:网络连接问题;读函数readssize_tread(intfd,void*buf,size_tnbyte)成功时,返回实际读的字节数;返回0,表示文件尾;返回0,表示错误:(1)EINTR:中断错误;(2)ECONNREST:网络连接问题;第13页13基于TCP协议的网络程序结构serversocket()clientbind()listen()accept()write()/read()close()socket()connect()close()write()/read()第14页14TCPserver.cintsockfd,new_fd;structsockaddr_inserver_addr;structsockaddr_inclient_addr;int_port_tportnumber=1025;If((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1){};/*服务器端填充sockaddr结构*/bzero(&server_addr,sizeof(structsockaddr_in));server_addr.sin_family=AF_INET;server_addr.sin_addr.s_addr=htonl(INADDR_ANY);server_addr.sin_port=htons(portnumber);/*捆绑sockfd描述符*/if(bind(sockfd,(structsockaddr*)(&server_addr),sizeof(structsockaddr))==-1){};if(listen(sockfd,5))==-1){};第15页15while(1){/*服务器阻塞,直到客户程序建立连接*/sin_size=sizeof(structsockaddr_in);new_fd=accept(sockfd,(structsockaddr*)(&client_addr),&sin_size));write(new_fd,hello,strlen(hello));//发送信息close(new_fd);//该连接上的通信结束/*循环接收下一个连接*/}close(sockfd);//关闭整个服务器第16页16Tcpclient.cstructsockaddr_inserver_addr;intportnumber,nbytes;inet_aton(argv[1],&server_addr.sin_addr)//命令行读参数portnumber=atoi(argv[2]);if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1){};//建立套接字server_addr.sin_family=AF_INET;//填充服务端的资料server_addr.sin_port=htons(portnumber);/*发起连接*/if(connect(sockfd,(structsockaddr*)(&server_addr),sizeof(structsockaddr))==-1){};/*连接成功*/nbytes=read(sockfd,buffer,1024));//接收数据/*结束通信*/close(sockfd);第17页17说明头文件#includesys/types.h#includesys/socket.h#includearpa/inet.h#includenetinet/in.h#includestrings.h#includestdio.h#includeerrno.h第18页18编译gcc–otcpservertcpserver.cgcc–otcpclienttcpclient.c运行./tcpserver666./tcpclient192.168.1.111666第19页192.3基于UDP协议的网络编程2.3.1常用的收发函数2.3.2基于UDP协议的网络程序结构2.3.3UDP程序示例第20页20常用的收发函数intrecvfrom(intsockfd,void*buf,intlen,unsignedintflags,structsockaddr*from,int*fromlen)intsendto(intsockfd,constvoid*msg,intlen,unsignedintflags,structsockaddr*to,inttolen)第21页21基于UDP协议的网络程序结构serversocket()clientbind()connectrecv/sendrecvfrom/sendtoclose()socket()connect()close()recv/sendrecvfrom/sendto可选第22页22基于UDP协议的网络程序结构UDP套接字执行connect函数作用:记录对方IP地址和端口号,不执行TCP套接字的三次握手;执行connect函数的UDP套接字:不使用sendto函数,使用write/send函数;不使用recvfrom函数,使用read/recv/recvmsg函数;引发异步错误并返回所在进程;未执行连接的UDP套接字不接受异步错误;第23页23设计实现一个UDPserver和UDPClient,服务器在端口SERVER_PORT监听,客户端从控制台输入信息,发送到服务器,服务器返回给客户自己已经收到的信息。第24页24UD
本文标题:第2章 UnixLinux下的网络程序设计
链接地址:https://www.777doc.com/doc-3401364 .html