ImageVerifierCode 换一换
格式:DOCX , 页数:14 ,大小:22.79KB ,
资源ID:6500106      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/6500106.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(基于Linux的TCP网络编程.docx)为本站会员(b****5)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

基于Linux的TCP网络编程.docx

1、基于Linux的TCP网络编程基于Linux的TCP网络编程一.Linux下TCP编程框架TCP网络编程的流程包含服务器和客户端两种模式。服务器模式创建一个服务程序,等待客户端用户的连接,接收到用户的连接请求后,根据用户的请求进行处理;客户端模式则根据目的服务器的地址和端口进行连接,向服务器发送请求并对服务器的响应进行数据处理。1.服务器端程序包括 建立套接字( socket()) 套接字与端口的绑定(bind() 设置服务器的侦听连接(listen()) 接收客户端连接(accept()) 接收和发送数据(send(),recv()) 关闭套接字(close()2.说明1套接字初始化过程中,

2、根据用户对套接字的需求来确定套接字的选项。按照用户定义的网络类型,协议类型和具体的协议标号等参数来定以socket()函数。系统根据用户的需求生成一个套接字文件描述符供用户使用。2套接字与端口的绑定过程中,将套接字与一个地址结构进行绑定。绑定之后,套接字所代表IP地址和端口地址及协议类型等参数按照绑定值进行操作。3由于一个服务器需要满足多个客户端的连接请求,而服务器在某个时间仅能处理有限个数的客户端连接请求,所以服务器需要设置服务器端排队队列的长度。4在客户端发送连接请求之后,服务器需要接收客户端的连接,然后才能进行其他的处理。5在服务器接收客户端请求之后,可以从套接字文件描述符中读取数据或者

3、向文件描述符发送数据。接收数据后服务器按照定义的规则对数据进行处理,并将结果发送给客户端。6当服务器处理完数据,要结束与客户端的通信过程的时候,需要关闭套接字连接2.客户端程序包括 建立套接字(socket() 连接服务器(connect() 读写网络数据(send(),recv() 关闭套接字(close()3.服务器端和客户端程序的区别客户端程序和服务器端程序不同之处是客户端在建立套接字之后可以不进行地址绑定,而是直接连接服务器端。服务器端有listen()和accept()两个函数,而客户端不需要这两个函数。二.基于Linux的TCP套接字函数1. socket1 函数原型:int so

4、cket(int domain,int type,int protocol)2 函数功能:函数socket()用于创建一个套接字描述符。3 形参: domain:用于指定创建套接字所使用的协议族,在头文件中定义。有时候程序中会使用PF_INET,在头文件中AF_INET和PF_INET的数值是一致的。常见的协议族如下:AF_UNIX:创建只在本机内进行通信的套接字。AF_INET:使用IPv4TCP/IP协议AF_INET6:使用IPv6 TCP/IP协议说明:AF_UNIX只能用于单一的UNIX系统进程间通信,而AF_INET是针对Interne的,因而可以允许在远程主机之间通信。一般把它赋

5、为AF_INET。 type:指明套接子通信的类型,对应的参数如下SOCK_STREAM:创建TCP流套接字SOCK_DGRAM:创建UDP数据报套接字SOCK_RAW:创建原始套接字 protocol:指定某个协议的特定类型参数protocol通常设置为0,表示通过参数domain指定的协议族和参数type指定的套接字类型来确定使用的协议。当为原始套接字时,系统无法唯一的确定协议,此时就需要使用使用该参数指定所使用的协议。4 返回值:执行成功后返回一个新创建的套接字;若有错误发生则返回一个-1,错误代码存入errno中。5 举例:调用socket函数创建一个UDP套接字int sock_fd

6、;sock_fd = socket(AF_INET,SOCK_DGRAM,0);if(sock_fd 函数原型:int bind(int sockfd,struct sockaddr *my_addr,socklen_t addrlen)2 函数功能函数bind()的作用是将一个套接字文件描述符与地址和端口绑定。3 形参: sockfd:sockfd是调用socket函数返回的文件描述符; addrlen是sockaddr结构的长度。 my_addr: 是一个指向sockaddr结构的指针,它保存着本地套接字的地址(即端口和IP地址)信息。不过由于系统兼容性的问题,一般不使用这个结构,而使用另

7、外一个结构(structsockaddr_in)来代替4 套接字地址结构:(1)struct sockaddr:结构struct sockaddr定义了一种通用的套接字地址,它在sys/socket.h 中定义。struct sockaddr unsigned short sa_family;/*地址类型,AF_XXX*/ char sa_data14;/*14字节的协议地址*/a. sin_family:表示地址类型,对于使用TCP/IP协议进行的网络编程,该值只能是AF_INET.b. sa_data:存储具体的协议地址。(2)sockaddr_in每种协议族都有自己的协议地址格式,TCP

8、/IP协议组的地址格式为结构体struct sockaddr_in,它在netinet/in.h头文件中定义。structsockaddr_in unsigned short sin_family;/*地址类型*/ unsigned short sin_port;/*端口号*/ struct in_addr sin_addr;/*IP地址*/ unsigned char sin_zero8;/*填充字节,一般赋值为0*/a. sin_family:表示地址类型,对于使用TCP/IP协议进行的网络编程,该值只能是AF_INET.b. sin_port:是端口号c. sin_addr:用来存储32

9、位的IP地址。d. 数组sin_zero为填充字段,一般赋值为0.e. struct in_addr的定义如下:structin_addr unsigned long s_addr;结构体sockaddr的长度为16字节,结构体sockaddr_in的长度为16字节。可以将参数my_addr的sin_addr设置为INADDR_ANY而不是某个确定的IP地址就可以绑定到任何网络接口。对于只有一IP地址的计算机,INADDR_ANY对应的就是它的IP地址;对于多宿主主机(拥有多个网卡),INADDR_ANY表示本服务器程序将处理来自所有网络接口上相应端口的连接请求5 返回值:函数成功后返回0,当

10、有错误发生时则返回-1,错误代码存入errno中。6举例:调用socket函数创建一个UDP套接字struct sockaddr_in addr_serv,addr_client;/*本地的地址信息*/memset(&serv_addr,0,sizeof(structsockaddr_in);addr_serv.sin_family= AF_INET;/*协议族*/addr_serv.sin_port= htons(SERV_PORT);/*本地端口号*/addr_serv.sin_addr.s_addr= htonl(INADDR_ANY); /*任意本地地址*/*套接字绑定*/if(bin

11、d(sock_fd,(structsockaddr *)&addr_serv),sizeof(struct sockaddr_in) 函数功能:函数listen()用来初始化服务器可连接队列,服务器处理客户端连接请求的时候是顺序处理的,同一时间仅能处理一个客户端连接。当多个客户端的连接请求同时到来的时候,服务器并不是同时处理,而是将不能处理的客户端连接请求放到等待队列中,这个队列的长度由listen()函数来定义。2函数原型:#includint listen(int sockfd,int backlog);3形参 sockfd: sockfd是调用socket函数返回的文件描述符 backl

12、og:指定该连接队列的最大长度。如果连接队列已经达到最大,之后的连接请求被服务器拒绝。大多数系统的设置为20,可以将其设置修改为5或者10,根据系统可承受负载或者应用程序的需求来确定。4返回值:当listen()函数成功运行时,返回值为0;当运行失败时,它的返回值为-1,错误代码存入errno中。5.listen()函数的例子:#define SERV_PORT 3000int main(int argc,char *argv)int sock_fd;struct sockaddr_in addr_serv,addr_client;/*本地的地址信息*/sock_fd = socket(AF_

13、INET,SOCK_DGRAM,0);if(sock_fd 0) perror(“socket”); exit(1);memset(&serv_addr,0,sizeof(structsockaddr_in);addr_serv.sin_family= AF_INET;/*协议族*/addr_serv.sin_port= htons(SERV_PORT);/*本地端口号*/addr_serv.sin_addr.s_addr= htonl(INADDR_ANY); /*任意本地地址*/*套接字绑定*/if(bind(sock_fd,(structsockaddr *)&addr_serv),si

14、zeof(struct sockaddr_in) 0) perror(“bind”); exit(1);/设置服务器侦听队列的长度if(listen(sock_fd,5) 函数功能:当一个客户端的连接请求到达服务器主机侦听的端口时,此时客户端的连接会在队列中等待,知道使用服务器处理接收请求。函数accept()成功执行后,会返回一个新的套接口文件描述符来表示客户端的连接,客户端连接的信息可以通过这个新描述符来获得。因此当服务器成功处理客户端的请求连接后,会有两个文件描述符,老的文件描述符表示客户端的连接,函数send()和recv()通过新的文件描述符进行数据收发。2函数原型:#include

15、#includeintaccept(int sock_fd,struct sockaddr*addr,socklen_t *addrlen);3形参 sock_fd:是由函数socket创建,经函数bind绑定到本地某一端口上,然后通过函数listen转化而来的监听套接字。 addr:用来保存发起连接请求的主机的地址和端口。 addrlen是addr 所指向的结构体的大小。4返回值:accept()函数的返回值是新连接的客户端套接字文件描述符,与客户端之间的通信是通过accept()返回的新套接字文件描述符来进行的,而不是通过建立套接字时的文件描述符。如果accept()函数发生错误,acce

16、pt()会返回-1,通过errno可以得到错误值。5如果参数sock_fd所指定的套接字被设置为阻塞方式(Linux下的默认方式),且连接请求队列为空,则accept()将被阻塞直到有连接请求到此为止;如果参数s所指定的套接字被设置为非阻塞方式,如果队列为空,accept将立即返回-1,errno被设置为EAGAIN.6实例:int client_fd;int client_len;struct sockaddr_in client_addr;client_len = sizeof(struct sockaddr_in);client_fd = accept(sock_fd,(struct s

17、ockaddr *)&client_addr,&client_len);if(conn_fd函数功能:客户端在建立套接字之后,不需要进行地址绑定,就可以直接连接服务器。连接服务器的函数为connect(),此函数连接指定参数的服务器,例如IP地址,端口号。如果是TCP编程,则connect()函数用于服务器发出连接请求,服务器的IP地址和端口号由 参数serv_addr指定。如果是UDP编程,则connect函数并不建立真正的连接,它只是告诉内核与该套接字进行通信的目的地址(由第二个参数指定),只有该目的地址发来的数据才会被该socket接收。调用connect函数的好处是不必在每次发送和接收

18、数据时都指定目的地址。2函数原型:#include#includeint connect(int sock_fd,struct sockaddr *serv_addr,socklen_taddrlen);3形参: sock_fd:建立套接字时返回的套接字文件描述符,调用socket()返回的。 serv_addr:是一个指向数据结构sockaddr的指针,其中包括客户端需要连接的服务器的目的IP地址和端口号。 addrlen:表示了第二了参数的大小,可以使用sizeof(struct sockaddr)4执行成功后返回0,有错误发生则返回-1,错误代码存入errno中。5实例:int sock

19、_fd;struct sockaddr_in serv_addr;if(-1 = (sock_fd = socket(AF_INET,SOCK_STREAM,0) printf(“Error: Unable to createsocket(%i)n”,errno); perror(“sockets”); exit(1);memset(&serv_addr,0,sizeof(structsockaddr_in);serv_addr.sin_family= AF_INET;serv_addr.sin_port= htons(DEST_PORT);serv_addr.sin_addr.s_addr=

20、 inet(DEST_IP_ADDRESS);if(-1= connect(sock_fd,(struct sockaddr *)&serv_add,sizeof(struct sockaddr) printf(“Error:unable to the establishconnection to socket(%i)n”,errno); perror(“socks”); close(sock_fd); exit(1);6. send(发送数据)1函数功能:函数send用来在TCP套接字上发送数据,send只能对处于连接状态的套接字使用。2函数原型#include#includessize_t

21、 send(int conn_fd,const void *msg,size_t len, int flags);3函数形参: conn_fd:为已建立好连接的套接字描述符,即调用accept()函数后返回的套接字描述符。 msg:存放发送数据的缓冲区。 len:发送缓冲区的长度 flags:为控制选项,一般设置为0,或取以下值: MSG_OOB:在指定的套接字上发送带外数据(out-of-band data),该类型的套接字必须支持带外数据(如:SOCK_STREAM). MSG_DONTROUTE:通过最直接的路径发送数据,而忽略下层协议的路由设置。4返回值:执行成功返回实际发送数据的字节

22、数,出错则返回-1,错误代码存入errno中。执行成功只是说明数据写入套接字的缓冲区中,并不表示数据已经成功地通过网络发送到目的地。5实例:#define BUFFERSIZE1500char send_bufBUFFERSIZE;if(send(conn_fd,send_buf,len,0)函数功能:recv()用来TCP套接字上接收数据。函数recv从指定的套接字描述符上接收数据并保存到指定buf中。2函数原型#include#includessize_t recv(int conn_fd,void *buf,size_t len,int flags);3函数形参: conn_fd: 为已

23、建立好连接的套接字描述符,即调用accept()函数后返回的套接字描述符 buf:接收缓冲区 len:接收缓冲区的大小 flags:为控制选项,一般设置为0或取以下数值 MSG_OOB:请求接收带外数据 MSG_PEEK:只查看数据而不读出 MSG_WAITALL:只在接收缓冲区满时才返回。4函数返回值函数执行成功返回接收到的数据字节数,出错返回-1,错误代码存入errno中。5实例:#define BUFFERSIZE1500charrecv_bufBUFFERSIZE;if(recv(conn_fd,recv_buf,sizeof(recv_buf),0)函数原型:int close(in

24、t fd);2函数功能:函数close用来关闭一个套接字描述符。3函数形参: 参数fd为一个套接字描述符。4返回值:执行成功返回0,出错则返回-1.错误代码存入errno中。说明:close()函数的头文件是#include.三.基于Linux的TCP套接字编程实例1.实例程序分为服务器端和客户端,客户端把Hello tigerjibo发送给服务器端;服务器端接收到字符串后,发送接收到的总字符串个数给客户端;2.服务器端程序:1 #include 2 #include 3 #include 4 #include 5 6 7 #include 8 #include 9 #include/clos

25、e()10 #include/struct sockaddr_in11 #include/inet_ntoa12 #define QUEUE_LINE 1213 #define SOURCE_PORT 80001415 #define SOURCE_IP_ADDRESS 192.168.1.61617 void process_info(int s)18 19 int recv_num;20 int send_num;21 char recv_buf50;22 char send_buf50;23 while(1)24 printf(begin recv:n);25 recv_num = re

26、cv(s,recv_buf,sizeof(recv_buf),0);26 if(recv_num 0)27 perror(recv);28 exit(1);29 else 30 recv_bufrecv_num = 0;31 printf(recv sucessful:%sn,recv_buf);32 33 sprintf(send_buf,recv %d numbers bytesn,recv_num);34 printf(begin sendn);35 send_num = send(s,send_buf,sizeof(send_buf),0);36 if (send_num 0)37 perror(sned);38 exit(1);39 else 40 printf(send sucessn);41 42 43 44 int main()45 46 int sock_fd,conn_fd;47 int client_len;48 pid_t pid;49

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1