tcp协议网络编程实现两台计算机通信(详细注释)

上传人:xzh****18 文档编号:33920143 上传时间:2018-02-19 格式:DOC 页数:4 大小:45KB
返回 下载 相关 举报
tcp协议网络编程实现两台计算机通信(详细注释)_第1页
第1页 / 共4页
tcp协议网络编程实现两台计算机通信(详细注释)_第2页
第2页 / 共4页
tcp协议网络编程实现两台计算机通信(详细注释)_第3页
第3页 / 共4页
tcp协议网络编程实现两台计算机通信(详细注释)_第4页
第4页 / 共4页
亲,该文档总共4页,全部预览完了,如果喜欢就下载吧!
资源描述

《tcp协议网络编程实现两台计算机通信(详细注释)》由会员分享,可在线阅读,更多相关《tcp协议网络编程实现两台计算机通信(详细注释)(4页珍藏版)》请在金锄头文库上搜索。

1、 3.试用 C 语言编写一对在以太网中发送和接收数据帧的应用,建议采用 Socket的 TCP 协议端口,必须提供软件设计方案和流程图,软件代码的每一行都必须加注中文注释说明设计意图,不得抄袭。 (必做题)解答: 编程使用 TCP/IP 协议,采用数据流的 socket 套接口,TCP 是面向连接的通信协议,通过三次握手建立连接,通讯完成时要拆除连接,由于 TCP 是面向连接的所以只能用于点对点的通讯。对比一下,UDP 是面向无连接的通讯协议,UDP 数据包括目的端口号和源端口号信息,由于通讯不需要连接,所以可以实现广播发送,UDP 通讯时不需要接收方确认,属于不可靠的传输,可能会出丢包现象。

2、程序采用服务器/客户机模式,下面是服务器的程序设计方案【1】 首先利用 socket 系统调用获得一个套接口【2】 系统调用 bind 将这个套接口绑定到主机的某个端口上【3】 端口开始侦听有无连接请求,系统调用 listen【4】 没有就继续侦听,有的话执行下一步【5】 接受 connect 的请求,系统调用 accept(),得到一个新的套接口描述符,这个时候通信管道已经完全建立好了【6】 利用这个新的描述符完成发送数据帧的操作,系统调用 send()【7】 发送完毕要撤销套接口下面是完整程序和详细注释清单 01 server.c#include#include#include#inclu

3、de#include#include#include#include /头文件#define MYPORT 3490 /定义用于通信的端口号#define BACKLOG 10 /定义等待队列中最多存放的 connect 请求个数main() /主函数这里开始int sockfd,new_fd; /这两个是调用 socket()系统调用得到的文件描述符struct sockaddr_in my_addr; /结构体定义,这是自己和对方的套接口的地址信息struct sockaddr_in their_addr;int sin_size; /其实这是 accept()里面的第三个参数,这里先定义

4、if(sockfd=socket(AF_INET,SOCK_STREAM,0)=-1)perror(socket); /进入正题,首先 socket()系统调用,sockfd 就是exit(1); /所得套接口的文件描述符,如果调用失败,perror 会 /显示错误信息,然后非正常退出my_addr.sin_family=AF_INET; / ADDRESS FAMILY 地址族my_addr.sin_port=htons(MYPORT);/ 把整数 MYPORT 转换成“网络字节顺序”my_addr.sin_addr.s_addr=INADDR_ANY;/ 使用自己的 IP 地址, 自动填上

5、它所运行的机器的 IP 地址bzero(/结构体中剩下的清 0上面是第一步,调用 socket()得到了一个套接口,下面将调用 bind()将其绑定到本地计算机的某个端口上,当然这里就是前面定义的那个端口if(bind(sockfd,(struct sockaddr *)&my_addr,sizeof(struct sockaddr)=-1)perror(bind); /如果失败就显示 bind()调用出错原因,成功的话 exit(1); /就继续往下运行其实利用 TCP/IP 协议进行数据流的传输就像两个地方搭个管道输送水流一样,现在这里是水电站,前面两步已经弄好了一个出水口,下面就要监听对

6、方是否需要我送水过去,运行 listen()系统调用。假如你不希望与远程的一个地址相连,那你就需要等待接入请求并且用各种方法处理它们。处 理过程分两步:首先,你听-listen() ,然后,你接受-accept() (请看下面的 内容) 。if (listen(sockfd,BACKLOG)=-1) /BACKLOG 是在进入 队列中允许的连接数目,进入的连接是在队列中一直等待直 到接受 (accept() ) 连接perror(listen); /在错误的时候返回 -1,并 设置全局错误变量 errnoexit(1);下面就是接受一个连接请求了while(1)sin_size=sizeof(

7、struct sockaddr_in);if(new_fd=accept(sockfd,(struct sockaddr *)&their_addr,&sin_size)=-1)perror(accept); /注意这里出现了第二个文件描述符,如果只想让一个连接进来,那么你可以使用 close() 去关闭原 来的文件描述符 sockfd 来避免同一个端口更多的连接continue; /如果没有成功接受的话就继续监听然后 acceptprintf(server:got connection from %sn,inet_ntoa(their_addr.sin_addr);连接上了要输出一个反馈信息

8、:server:got connection from+客户端的 ip 地址然后就把数据帧发送过去,调用 send() ,当然我们不用去关心这个数据帧是怎么被包装的,这些交给下层处理,fork()产生一个子进程用来发送数据if(!fork()if (send (new_fd,hello,world!n,14,0)=-1)perror(send);close(new_fd);exit(0);close(new_fd); 发送完毕即时的关掉套接口while(waitpid(-1,NULL,WNOHANG)0); 最后释放子进程的资源,防止产生僵尸进程造成资源没有释放。至此服务器程序设计完毕,下面着

9、手客户机的程序设计,与服务器相比客户端的设计相对简单一些,其程序设计流程大致如下【1】 系统调用 socket()获得套接口【2】 由于我是要连到远方服务器端口,所以我不必绑定到自己的机器端口上,故而有了套接口下面可以直接向远方主机发送 connect 连接请求【3】 如果 connect 失败,那就返回第二步,继续 connect,直到成功【4】 连接成功后通信管道就建好了,可以调用 recv()来接受数据帧【5】 最后把套接口释放掉下面是完整程序和详细注释清单 02 user.c#include#include#include#include#include#include#include

10、#include /头文件#define PORT 3490 / 端口号定义,这就是将要连接到的端口#define MAXDATASIZE 100 /这个参数是一次所能得到的最大字节数下面开始主函数,注意 main 函数是有参数的,argc=参数的个数+1,因为函数自身算一个参数,数组 argv用来依次存放指向参数的指针int main(int argc,char *argv) 前面都是对一些参数类型进行声明int sockfd,numbytes; char bufMAXDATASIZE;struct hostent *he;struct sockaddr_in their_addr; 首先检

11、验 main 函数是不是给了 1 个参数,是一个啊得注意if(argc != 2)fprintf(stderr,usage:client hostnamen); 如果参数不是一个就报错exit(1); 然后非正常退出然后检验参数(其实这个参数就是服务器的 ip 地址 ,参数的指针就在 argv1里面)是否有效,调用函数 gethostbyname(),它的基本原理就是得到和你主机名字相匹配的 ip 地址。if(he=gethostbyname(argv1)=NULL)herror(gethostbyname); 出错的话返回出错信息exit(1);能运行到这一步说明参数个数和参数内容都是正确的

12、,其实这才是真正的开始调用 socket()得到套接口,sockfd 为返回的套接口描述符if(sockfd=socket(AF_INET,SOCK_STREAM,0)=-1)perror(socket);exit(1); 下面的跟之前服务器端程序差不多,是对套接口信息初始化their_addr.sin_family=AF_INET;their_addr.sin_port=htons(PORT);their_addr.sin_addr=*(struct in_addr *)he-h_addr);bzero(可以继续用我的那个比喻,如果服务器是水库,并且那里已经有个出口在侦听是不是有人要水流,那

13、么我是用户,并且程序运行到这我也已经有了一个入口地址,是时候跟服务器取得联系了,一旦联系成功,立马就会建立一条管道,下面就是 connect()系统调用if(connect(sockfd,(struct sockaddr *)&their_addr,sizeof(struct sockaddr)=-1)perror(connect);exit(1);连接成功,此时服务器的 listen()监听到了我的 connect,并且 accept 了我,然后 send 了数据帧给我,所以接下来我就得接受数据帧了,用到系统调用recv()if(numbytes=recv(sockfd,buf,MAXDAT

14、ASIZE,0)=-1)perror(recv);exit(1);收到的数据存放到数组 buf中,对于字符串数组最后一个停止位记得给加上bufnumbytes=0;把收到的信息显示出来吧printf(received:%s,buf);最后关闭套接口,释放端口close(sockfd);return 0; 至此完成用户程序的编写,采用 linux 编译环境,编译连接后,运行调试在我的电脑上同时开两个窗口,分别模拟服务器和用户,键入Ifconfig 命令查看本机的 ip 地址,显示本地环回 inet 地址 127.0.0.1运行 ./server 服务器开始运行然后 ./user 127.0.0.1 用户程序运行运行结果:服务器端显示 server:got connection from 127.0.0.1客户端显示 received:hello,world!PS:我昨天运行的时候键入 ifconfig 出来好多 ip 地址,不止一个 127.0.0.1,还有个 180.109.92.243 我试过,也可以顺利通信,另外一个 62.记不清了反正这个不行,但是今晚再次运行 ifconfig 只有一个 127.0.0.1 出现,没有180.109.92.243,键入这个参数提示说 network is unreachable,这次不行了

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 商业/管理/HR > 商业合同/协议

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号