基于以太网跨平台双机会话.docx

上传人:b****3 文档编号:2804521 上传时间:2022-11-15 格式:DOCX 页数:14 大小:83.95KB
下载 相关 举报
基于以太网跨平台双机会话.docx_第1页
第1页 / 共14页
基于以太网跨平台双机会话.docx_第2页
第2页 / 共14页
基于以太网跨平台双机会话.docx_第3页
第3页 / 共14页
基于以太网跨平台双机会话.docx_第4页
第4页 / 共14页
基于以太网跨平台双机会话.docx_第5页
第5页 / 共14页
点击查看更多>>
下载资源
资源描述

基于以太网跨平台双机会话.docx

《基于以太网跨平台双机会话.docx》由会员分享,可在线阅读,更多相关《基于以太网跨平台双机会话.docx(14页珍藏版)》请在冰豆网上搜索。

基于以太网跨平台双机会话.docx

基于以太网跨平台双机会话

第2章基于以太网的跨平台双机会话

该综合实验是基于嵌入式开发平台以太网口的应用,利用Microwindows的可视化界面建立交互平台,再利用uClinux的socket编程实现PC机与开发平台之间的信息交互。

本章在实验预备知识部分提供了网络编程以及双机交互工作流程的相关知识,在后面介绍了实验操作步骤及主要程序代码分析。

2.1实验目的

☉学习嵌入式Linux网络编程的方法,熟悉网络通信中套接字的使用。

☉掌握Microwindows的配置以及Microwindows窗口绘制和事件编程。

2.2实验设备及工具

☉硬件:

ARM嵌入式开发板、PC机Pentumn500以上,硬盘10G以上。

☉软件:

PC机操作系统redhatlinux9.0+uclinux开发环境,

Microwindows安装包。

2.3实验内容

利用Microwindows的可视化界面建立交互平台,采用数据报通信方式实现基于图元传输的多机实时交互。

2.4实验预备知识

1、MicroWindows开放源码的嵌入式GUI软件的使用知识。

关于这方面的知识参见〈嵌入式系统原理与接口技术实验指导书〉以及第1章相关部分。

2、uClinux的socket编程知识

socket是网络通信中应用进程和网络协议之间的一种网络编程接口,它是对通信端点的一种抽象,提供了一种发送和接受数据的机制。

再Linux系统中,socket属于文件系统的一部分,网络通信可以被看作是对文件的读取。

〈1〉socket编程常用函数

uClinux具有优秀的网络功能,提供和linux一样的socket系统调用函数。

下面是编制程序常用的系统调用函数:

①.socket():

分配socket

应用程序在使用socket之前,首先必须拥有一个socket。

socket()向应用程序提供创建socket的手段。

socket()函数原形如下:

 int socket(intdomain,inttype,intprotocol);

参数说明:

domain:

说明网络程序所在的主机采用的通信协议(AF_UNIX和AF_INET等)。

AF_INET是针对Internet的,允许在远程主机之间通信。

Type:

网络程序所采用的通信协议(SOCK_STREAM,SOCK_DGRAM等)。

其中SOCK_STREAM表明用的是TCP协议。

Protocol:

由于指定了type,所以一般用0来代替。

②.bind():

绑定本地地址

bind()函数给已经打开的socket指定本地地址。

函数原形如下:

intbind(intsockfd,structsockaddr*my-addr,intaddrlen);

参数说明:

sockfd:

是由socket()调用返回的文件描述符。

Addrlen:

是sockaddr结构的长度。

my-addr:

是一个指向sockaddr的指针。

③.listen():

准备接受连接请求

在用bind()给一个socket设定本地地址之后,就可以将这个socket用于接受连接请求,即listen()。

函数原形如下:

intlisten(intsockfd,intbacklog);

参数说明:

sockfd:

是调用过bind()后的文件描述符。

Backlog:

设置请求排队的最大长度。

④.accept():

接受指定socket上的连接请求

在系统调用listen()之后,系统就在socket的连接请求暂存队列里存放每一个向该socket建立的连接请求,accept()的作用是从该暂存队列中取出一个连接请求,用该socket的数据,创建一个新的socket。

函数原形如下:

intaccept(intsockfd,void*addr,int*addrlen);

参数说明:

sockfd:

是listen后的文件描述符。

addr、addrlen:

这两个参数将会被客户端的程序填写,服务器端只要传递指针就可以了,它用来描述连接进来的客户端的信息。

⑤.connect():

建立连接

bind(),listen()和accept()都是用于被动地等待对方建立连接时需要使用的,connect()函数是在主动地向对方建立连接时使用的。

函数原形如下:

intconnect(intsockfd,structsockaddr*serv_addr,intaddrlen);

参数说明:

sockfd:

socket返回的文件描述符。

serv_addr:

存储了服务器端的连接信息。

Addrlen:

serv_addr的长度,可以使用sizeof(structsockaddr)获得。

⑥.send(),recv():

用于socket的发送和接收数据

在连接建立完成后,通信双方就可以使用以上这些函数来进行数据的发送和接收操作。

send(),recv()函数原形如下:

intsend(intsockfd,constvoid*msg,intlen,unsignedintflags);

intrecv(intsockfd,void*buf,intlen,unsignedintflags);

参数说明:

sockfd:

希望进行数据传递的套接口的文件描述符。

asg:

指向希望发送的数据的指针。

len:

对于发送来说,它是希望发送的数据的字节长度。

若是recv(),则它表示接收缓冲的最大长度。

flags:

这个参数可以是0或者是下表中的各项的组合。

Flags参数选项

宏定义

含义

MSG_DONTROUTE

不查找路由表

MSG_OOB

接收或者发送带外数据

MSG_WAITALL

等待所有数据

MSG_PEEK

查看数据,并不从系统缓冲区移走数据

●MSG_DONTROUTE:

是send()函数使用的标志,这个标志告诉IP协议目的主机再本地网络上面,没有必要查找路由表。

●MSG_OOB:

表示可以接收和发送带外的数据。

●MSG_WAITALL:

是recv()函数的使用标志,表示等到所有的信息到达时才返回。

●MSG_PEEK:

是recv()函数的使用标志,表示只是从系统缓冲区中读取内容,而不改变系统缓冲区中的内容。

⑦.Sendto():

指定目的地址

因为数据报套接口是无连接,它并不连接到远程的主机上,所以再发送数据包之前,必须首先给出目的地址。

函数原型如下:

intsendto(intsockfd,constvoid*msg,intlen,unsignedintflags,conststructsockaddr*to,inttolen);

除了最后两个参数以外,其他的参数含义与系统调用send()时相同。

其中,参数to是指向包含目的IP地址和端口号的数据结构sockaddr的指针。

参数tolen可以设置为sizeof(structsockaddr)。

⑧.close():

关闭socket

socket和文件描述符的关闭操作都使用这个函数。

函数原形如下:

intclose(sockfd);

调用这个函数以后,就不能再对此套接口进行任何的读写操作了。

〈2〉.数据流和数据报通信

网络通信最常用的Internet套接字分为三种类型:

数据流套接字、数据报套接字及原始套接字。

数据流套接字定义了一种可靠的面向连接的服务,实现了无差错无重复的顺序数据传输;数据报套接字定义了一种无连接的服务,数据通过相互独立的报文进行传输,是无序的,并且不保证可靠,无差错;原始套接字允许对低层协议如IP或ICMP直接访问,主要用于新的网络协议实现的测试等。

数据报套接字使用UDP来传送数据包,所以数据报的顺序是没有保障的。

数据报是按一种应答的方式进行数据传输的。

下面对数据流通信和数据报通信的方式分别加以说明。

1.数据流通信

数据流套接字是基于TCP的,与网络通信协议相符合,它是面向连接的,能提供一种可靠的服务。

整个面向连接的数据流通信的socket编程过程可用图2-1来表示:

图2-1数据流通信过程

使用socket的数据流进行通信的过程如下:

首先启动服务器,通过调用socket()建立一个套接字,然后调用bind()将该套接字和本地网络地址联系在一起,再调用listen()使套接字做好侦听的准备,并规定它的请求队列的长度,当远程的客户机试图使用connect()连接listen()正在监听的端口时,连接将会在队列中等待,直到调用accept()来处理它。

在accept()处理了连接请求后,将会生成一个新的描述这个连接端口的套接字,利用这个套接字就可以发送和接收数据了。

如果listen()一直没有侦听到连接请求,那么服务器任务就会在accept()处阻塞(在阻塞模式下),一直到有连接请求到来。

对于客户机任务来说,它也需要先用socket()建立一个通信端口,但是它不必用bind()把一个本地地址绑定到这个端口上,而是直接使用connect()向指定的服务器发送连接请求,如果请求被接收,下一步就可以进行数据流通信了。

②.数据报通信

对于数据报通信的服务器端来说,它不必再在一个端口上侦听,以等待建立连接,而只需生成一个端口描述符,并且把这个端口描述符绑定到本地地址上就可以了。

对于客户端也是一样。

这样整个通信过程就简洁的多。

需要说明的是,UDP的客户端可以使用connect(),但是这时使用connect()并不真正产生连接,而只是填写对端套接字的有关信息。

使用connect()的好处是,随后的程序通信中不必每次指定地址,即可以使用recv()、send()等进行通信。

否则,就应该使用recvfrom()、sendto()等实现函数通信,而每次都指定对端地址信息。

数据报通信的通信过程见图5-3所示。

图2-2数据报通信过程

socket编程高级特性

在socket应用编程中,还有许多高级应用特性,如获取服务器和客户机主机信息、进行阻塞处理、设置服务器工作模式、使用原始套接字等,下面对这些特性加以介绍。

1.获取服务器和客户机主机信息

(1)IP地址和域名的转换

在网络上标识一台机器时即可采用IP或者也可采用域名,那么怎样实现两者的转换呢?

可以使用如下函数:

structhostent*gethostbyname(constchar*hostname)

structhostent*gethostbyaddr(constchar*addr,intlen,inttype)

 

至于返回的数据结构structhostent,在中有它的定义:

structhostent{

charh_name;/*主机的正式名称*/

charh_aliases;/*主机的别名*/

inth_addrtype;/*主机的地址类型AF_INET*/

inth_length;/*主机的地址长度,对于IP4是4个字节32位*/

char**h_addr_list;/*主机的IP地址列表*/

}

#defineh_addrh_addr_list[0]/*主机的第一IP地址*/

gthostbyname()可以将机器名(如)转换为一个hostent结构指针,在这个结构里面储存了域名的地址信息。

Gethostbyaddr()可以将一个32位的IP地址(C0A80001)转换为结构指针,在这个结构里面储存了域名的地址信息。

这两个函数调用失败时返回NULL,且设置h_errno错误变量。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工程科技 > 电子电路

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

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