



下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、3.试用C语言编写一对在以太网中发送和接收数据帧的应用,建议采用Socket的TC呦议端口 ,必须提供软件设计方案和流程图,软件代码的每一行都必须加 注中文注释说明设计意图,不得抄袭。(必做题)解答:编程使用TCP/IP协议,采用数据流的socket套接口,TCP是面向连接的 通信协议,通过三次握手建立连接,通讯完成时要拆除连接,由于 TCP是面向 连接的所以只能用于点对点的通讯。对比一下,UDPH面向无连接的通讯协议,UD啜据包括目的端口号和源端口号信息,由于通讯不需要连接,所以可以实现 广播发送,UDPffi讯时不需要接收方确认,届于不可靠的传输,可能会出丢包现 象。程序采用服务器/客户机
2、模式,下面是服务器的程序设计方案11首先利用socket系统调用获得一个套接口【2】 系统调用bind将这个套接口绑定到主机的某个端口上【3】 端口开始侦听有无连接请求,系统调用listen【4】 没有就继续侦听,有的话执行下一步【5】 接受connect的请求,系统调用accept(),得到一个新的套接口描 述符,这个时候通信管道已经完全建立好了【6】 利用这个新的描述符完成发送数据帧的操作,系统调用 send ()【7】 发送完毕要撤销套接口下面是完整程序和详细注释活单 01 server.c#include<stdio.h> #include<stdlib.h>#
3、include<errno.h>#include<string.h>#include<sys/types.h>#include<netinet/in.h>/头文件/定义用于通信的端口号/定义等待队歹0中最多存放的connect请求个数#include<sys/socket.h>#include<sys/wait.h>#define MYPORT 3490#define BACKLOG 10main()/主函数这里开始int sockfd,new_fd;/这两个是调用socket。系统调用得到的文件描述符struct soc
4、kaddr_in my_addr;结构体定义,这是自己和对方的套接口的地址信息struct sockaddr_in their_addr;int sin_size;/其实这是accept ()里面的第三个参数,这里先定义 if(sockfd=socket(AF_INET,SOCK_STREAM,0)=-1)perror("socket");/进入正题,首先 socket ()系统调用,sockfd就是exit(1);/所得套接口的文件描述符,如果调用失败,perror会/显示错误信息,然后非正常退出my_addr.sin_family=AF_INET; / ADDRESS
5、FAMILY 地址族my_addr.sin_port=htons(MYPORT);/ 把整数 MYPORT 转换成“网络字节顺序”my_addr.sin_addr.s_addr=INADDR_ANY;/使用自己的IP地址,自动填上它所运一 一 一-行的机器的IP地址bzero(&(my_addr.sin_zero),8);结构体中剩下的活 0上面是第一步,调用socket。得到了一个套接口,下面将调用bind ()将其绑定到本地计算机的某个端口上,当然这里就是前面定义的那个端口if(bind(sockfd,(struct sockaddr *)&my_addr,sizeof(s
6、truct sockaddr)=-1)perror("bind");伽果失败就显示bind ()调用出错原因,成功的话exit(1);僦继续往下运行其实利用TCP/IP协议进行数据流的传输就像两个地方搭个管道输送水流一样, 现在这里是水电站,前面两步已经弄好了一个出水口,下面就要监听对方是否需要我送水过去,运行listen ()系统调用。假如你不希望与远程的一个地址相连, 那你就需要等待接入请求并且用各种方法处理它们。处理过程分两步:首先,你听-listen。,然后,你接受-accept()(请看下面的内容)。if (listen(sockfd,BACKLOG)=-1) /
7、BACKLOG是在进入队列中允许的连接数目,进入的连接是在队列中一直等待直至U接受(accept()旌接perror("listen"); /在错误的时候返回-1,并设置全局错误变量errno exit(1);下面就是接受一个连接请求了while(1)sin_size=sizeof(struct sockaddr_in);if(new_fd=accept(sockfd,(struct sockaddr *)&their_addr,&sin_size)=-1)perror("accept"); /注意这里出现了第二个文件描述符,如果只想让一
8、个连接 进来,那么你可以使用close()去关闭原 来的文件描述符sockfd来避免同一个端 口更多的连接continue;/如果没有成功接受的话就继续监听然后acceptprintf("server:got connection from %sn",inet_ntoa(their_addr.sin_addr);连接了要输出一个反馈信息:server:got connection from峪户端而ip地址然后就把数据帧发送过去,调用 send(),当然我们不用去关心这个数据帧是怎 么被包装的,这些交给下层处理,fork ()产生一个子进程用来发送数据if(!fork()if
9、 (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);最后释放子进程的资源,防止产生僵尸进程造成资源没有释放。至此服务器程序设计完毕,下面着手客户机的程序设计,与服务器相比客户端的 设计相对简单一些,其程序设计流程大致如下11系统调用socket ()获得套接口【2】 由于我是要连到远方服务器端口,所以我不必绑定到自己的机器端口上,
10、故而有了套接口下面可以直接向远方主机发送connect连接请求【3】 如果connect失败,那就返回第二步,继续 connect,直到成功【4】 连接成功后通信管道就建好了,可以调用recv()来接受数据帧【5】 最后把套接口释放掉 下面是完整程序和详细注释活单 02 user.c#include<stdio.h>#include<stdlib.h>#include<errno.h>#include<string.h>#include<netdb.h>#include<sys/types.h>#include<ne
11、tinet/in.h>#include<sys/socket.h>/头文件#define PORT 3490/端口号定义,这就是将要连接到的端口#define MAXDA TASIZE 100 /这个参数是一次所能得到的最大字节数下面开始主函数,注意 main函数是有参数的,argc=#数的个数+1,因为函数自 身算一个参数,数组argv用来依次存放指向参数的指针int main(int argc,char *argv)前面都是对一些参数类型进行声明int sockfd,numbytes;char bufMAXDA TASIZE;struct hostent *he;stru
12、ct sockaddr_in their_addr;首先检验main扁数是*是给了 1个参数,是一个啊得注意if(argc != 2)fprintf(stderr,"usage:client hostnamen");如果参数不是一个就报错exit(1);然后非正常退出然后检验参数(其实这个参数就是服务器的ip地址,参数的指针就在argv1里面) 是否有效,调用函数gethostbynameQ它的基本原理就是得到和你主机名字相匹 配的ip地址。if(he=gethostbyname(argv1)=NULL)herror("gethostbyname");出
13、错的话返回出错信息exit(1);能运行到这一步说明参数个数和参数内容都是正确的,其实这才是真正的开始调用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_
14、addr);bzero(&(their_addr.sin_zero), 8);可以继续用橱勺那个比硫,如果服务器是水库,并且那里已经有个出口在侦听是 不是有人要水流,那么我是用户,并且程序运行到这我也已经有了一个入口地址, 是时候跟服务器取得联系了,一旦联系成功,立马就会建立一条管道,下面就是connect ()系统调用if(connect(sockfd,(struct sockaddr *)&their_addr,sizeof(struct sockaddr)=-1) (perror("connect");exit(1);连接成功,此时服务器的listen
15、 0监听到了我的connect,并且accept了我,然 后send了数据帧给我,所以接下来我就得接受数据帧了,用到系统调用 recv() if(numbytes=recv(sockfd,buf,MAXDATASIZE,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用户程序运行运行结果:服务器端显示
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年线下演出市场复苏演出市场政策环境分析报告
- 2025年教育信息化资金申请报告:互联网+教育平台项目评估
- 熔接理论考试题及答案
- 车间厂房采购合同范本
- 违法用地出租合同范本
- 租车位交押金合同范本
- 民间私人投资合同范本
- 粉煤销售批发合同范本
- 民间排球比赛合同范本
- 沥青买卖合同三方协议
- 2025年时事政治考试100题及答案
- 2025年全国中小学校党组织书记网络培训示范班在线考试题库及答案
- 工程质量保证体系框图
- 疥疮防与治课件
- 饮食营养与健康课件
- 地下车库系统环氧地坪施工组织设计
- 2022年浙江省公务员录用考试《申论》试卷及参考答案
- 医共体成员单位人力资源工作制度
- YY∕T 0953-2020 医用羧甲基壳聚糖(高清正版)
- 生物医学工程导论课件
- 宠物市场调研报告
评论
0/150
提交评论