项目三智能物流WIFI传输网方案设计与实践.docx

上传人:b****7 文档编号:10633310 上传时间:2023-02-22 格式:DOCX 页数:22 大小:1.88MB
下载 相关 举报
项目三智能物流WIFI传输网方案设计与实践.docx_第1页
第1页 / 共22页
项目三智能物流WIFI传输网方案设计与实践.docx_第2页
第2页 / 共22页
项目三智能物流WIFI传输网方案设计与实践.docx_第3页
第3页 / 共22页
项目三智能物流WIFI传输网方案设计与实践.docx_第4页
第4页 / 共22页
项目三智能物流WIFI传输网方案设计与实践.docx_第5页
第5页 / 共22页
点击查看更多>>
下载资源
资源描述

项目三智能物流WIFI传输网方案设计与实践.docx

《项目三智能物流WIFI传输网方案设计与实践.docx》由会员分享,可在线阅读,更多相关《项目三智能物流WIFI传输网方案设计与实践.docx(22页珍藏版)》请在冰豆网上搜索。

项目三智能物流WIFI传输网方案设计与实践.docx

项目三智能物流WIFI传输网方案设计与实践

项目三智能物流WIFI传输网方案设计与实践

一、教学目标

1、掌握WIFI相关基础知识。

2、自行组建WIFI数据传输的流程和方法。

3、完成WIFI数据传输的流程和方法。

二、教学内容

3.1WIFI基础知识

1、WIFI概述

Wifi是一种可以将个人电脑、手持设备(如PDA、手机)等终端以无线方式互相连接的技术。

它是一个无线网路通信技术的品牌,由Wifi联盟所持有,目的是改善基于IEEE802.11标准的无线网路产品之间的互通性。

它是一种短程的无线传输技术,能够在数百英尺范围内支持互联网接入的无线电信号。

随着技术的发展,以及IEEE802.11a及IEEE802.11g等标准的出现,现在IEEE802.11这个标准已被统称作Wifi。

2、Wifi的组成

一个Wifi联接点网络成员和结构站点(Station),是网络最基本的组成部分。

基本服务单元(BasicServiceSet,BSS):

网络最基本的服务单元。

最简单的服务单元可以只由两个站点组成。

站点可以动态地联接(associate)到基本服务单元中。

分配系统(DistributionSystem,DS):

分配系统用于连接不同的基本服务单元。

分配系统使用的媒介(Medium)逻辑上和基本服务单元使用的媒介是截然分开的,尽管它们物理上可能会是同一个媒介,例如同一个无线频段。

接入点(AccessPoint,AP):

接入点既有普通站点的身份,又有接入到分配系统的功能。

拓展服务单元(ExtendedServiceSet,ESS):

由分配系统和基本服务单元组合而成。

这种组合是逻辑上的,并非物理上的。

不同的基本服务单元物有可能在地理位置上相去甚远。

分配系统也可以使用各种各样的技术。

关口(Portal):

也是一个逻辑成分。

用于将无线局域网和有线局域网或其他网络联系起来。

3、Wifi的特点

IEEE802.11只负责在站点使用的无线媒介上的寻址(Addressing),分配系统和其他局域网的寻址不属于无线局域网的范围。

IEEE802.11没有具体的定义分配系统,只是定义了分配系统应该提供的服务(Service)。

整个无线局域网定义了9种服务:

●5种服务属于分配系统的任务,分别为:

联接(Association),结束联接(Dissociation),分配(Distribution),集成(Integration),再联接(Reassociation)。

●4种服务属于站点的任务,分别为:

鉴权(Authentication),结束鉴权(Deauthentication),隐私(Privacy),MAC数据传输(MSDUdelivery)。

4、Wifi的应用

由于Wifi的频段在世界范围内是无需任何电信运营执照的,因此WLAN无线设备提供

了一个世界范围内可以使用的,费用极其低廉且数据带宽极高的无线空中接口。

用户可以在Wifi覆盖区域内快速的浏览网页,随时随地的接听拨打电话。

而其他一些基于WLAN的宽带数据应用,如流媒体、网络游戏等功能更是值得用户期待。

有了Wifi功能,我们可以打长途电话(包括国际长途),浏览网页、收发电子邮件、音乐下载、数码照片传递等,而无需担心速度慢和花费高的问题。

Wifi在掌上设备上应用越来越广泛,而智能手机就是其中一份子。

与早前应用于手机上的蓝牙技术不同,Wifi具有更大的覆盖范围和更高的传输速率,因此Wifi手机成为了目前移动通信业界的时尚潮流。

3.2WIFI传感网实践

3.2.1WIFI接入

1、接入设备

●天线

●ARM网关(EBA)

2、WIFI接入原理

(1)UDP

UDP是一个面向数据报和无连接的简单传输层协议.它不像TCP那样通过握手过程建立服务器与客户端的连接才可以工作。

在网络通信质量较好的情况下,UDP体现出高效率,这适合于传送少量报文的应用。

linux系统是通过套接字结构来进行网络编程的,应用程序通过对套接字的几个函数调用,会返回一个用于通信的套接字描述符,而Linux应用程序在进行任何形式的I/O操作时,程序实际上是在读写一个文件描述符。

因此Linux下的套接字编程,可以看成是对普通文件描述符的操作,这些操作与被使用的硬件平台无关,这是linux设备无关性的优点。

(2)Socket

常用的Socket类型有两种:

流式Socket(SOCK_STREAM)和数据报式Socket(SOCK_DGRAM)。

流式是一种面向连接的Socket,针对于面向连接的TCP服务应用;应用流式Socket可以保证数据传输中的完整性、正确性和单一性,可类比于现实生活中的打电话。

数据报式Socket是一种无连接的Socket,对应于无连接的UDP服务应用。

数据报式Socket可以象流式Socket一样进行数据的双向传输,但无法保证传输数据的完整性、正确性和单一性。

可以类比于现实生活中的寄信。

Socket并不是以面向对象的方式提供的。

Socket事实上并不是留给编程开发的,而是留给网络操作系统实现协议栈的一个支持模型。

例如berkeleySocket和windowsSocket。

至于编程开发时使用的Socket模型和相应的API,则是操作系统服务API。

事实上Socket也不是tcp/udp服务的全部而是部分。

如果用电话来对应网络会话的话,端口应该正好比分机号。

rawSocket其实就是跳过TCP,UDP这一层。

用Socket我们不光是只发数据了,还要TCP和UDP的头。

大家也可以自己一个字节一个字节来构建自己的IP数据报文,并非一定需要通过Socket接口。

(通过流行的winpcap,你可以抛开Socket,发送自己构建的任意的IP报文)。

Socket是一个大家都认为好用的构建和解析IP协议的接口而已(当然Socket并非仅仅能够构建和解析ip协议),其实有很多嵌入式设备还有其他的网络通讯接口(比如LWIP)。

只不过在大部分操作系统上Socket更加通用而已。

3、WIFI接入步骤

(1)ARM网关断电。

将天线插入wifi模块的SMA_WIFI部分,如图3-1所示:

图3-1wifi插入天线位置

(2)ARM网关上电,启动Linux系统。

(3)本小节中是一个WIFI连接路由的示例。

由于网络环境的不同,所以在您做本实验时,请根据实际情况进行设置。

(4)在终端内依次执行下面的命令连接路由器。

#ifconfig–a(检测开发板所有网卡状况)

#ifconfigeth0down(关闭dm9000网卡)

#ifconfigwlan0up(启动SDIOWIFI)

#iwlistwlan0scan(使用SDIOWIFI扫描无线网络设备)

#iwconfigwlan0essid“E-Box”(设置essid)

如果路由器不支持自动获取IP功能,则输入命令:

#ifconfigwlan0192.168.0.232(设置SDIOWIFI的IP)

若路由器支持自动获取IP功能,那么无需设置SDIOWIFI的IP,输入下面的命令:

#udhcpc–iwlan0

设置路由器访问密码,若路由器无密码则无需此命令。

#iwconfigwlan0key“123456789”

#routeadddefaultgw192.168.0.201(设置网关,路由器支持自动获取IP则无需此命令)

#ping192.168.0.201(ping网关)

本小节测试的路由器可以访问互联网,所以可以使用QTOPIA浏览器上网冲浪。

3.2.2WIFI数据交互

1、WIFI数据交互设备

●天线

●ARM网关(EBA)两个

●SD卡

2、WIFI数据交互实践原理

(1)Socket

TCP/IP(TransmissionControlProtocol/InternetProtocol)即传输控制协议/网间协议,是一个工业标准的协议集,它是为广域网(WANs)设计的。

TCP/IP协议族包括运输层、网络层、链路层。

Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。

在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。

TCP/IP仅仅是一套协议、规范,并没有实体存在,是完全抽象的;Socket模型则是清晰而具体的。

而大部分情况下,门面模型是可有可无的,只是为了满足封装一个简单的外部门面而存在的,TCP/IP和Socket并没有相提并论的前提,根本是为了解决同一个问题的两个步骤,是完全分离的。

抓包程序基本上是使用rawSocket(原始套接字)实现的,这是Socket的高级功能,并不是因为对TCP/IP协议很了解,而是对Socket很了解(当然不了解TCP/IP也无法理解高级的Socket)。

离开特定操作系统(或者虚拟机)讨论TCP/IP的编程是没有意义的。

Socket在其中的位置如图3-2所示:

图3-2Socket在网络协议中的位置

服务器端先初始化Socket,然后与端口绑定(bind),对端口进行监听(listen),调用accept阻塞,等待客户端连接。

在这时如果有个客户端初始化一个Socket,然后连接服务器(connect),如果连接成功,这时客户端与服务器端的连接就建立了。

客户端发送数据请求,服务器端接收请求并处理请求,然后把回应数据发送给客户端,客户端读取数据,最后关闭连接,一次交互结束。

如图3-3所示:

图3-3服务器与客户端之间交互过程

1)1Socket建立

为了建立Socket,程序可以调用Socket函数,该函数返回一个类似于文件描述符的句柄。

Socket函数原型为:

intSocket(intdomain,inttype,intprotocol);

domain指明所使用的协议族,通常为PF_INET,表示互联网协议族(TCP/IP协议族);type参数指定Socket的类型:

SOCK_STREAM或SOCK_DGRAM,Socket接口还定义了原始Socket(SOCK_RAW),允许程序使用低层协议;protocol通常赋值"0"。

Socket()调用返回一个整型Socket描述符,你可以在后面的调用使用它。

两个网络程序之间的一个网络连接包括五种信息:

通信协议、本地协议地址、本地主机端口、远端主机地址和远端协议端口。

Socket数据结构中包含这五种信息。

Bind函数将Socket与本机上的一个端口相关联,随后你就可以在该端口监听服务请求。

Bind函数原型为:

intbind(intsockfd,structsockaddr*my_addr,intaddrlen);

Sockfd是调用Socket函数返回的Socket描述符,my_addr是一个指向包含有本机IP地址及端口号等信息的sockaddr类型的指针;addrlen常被设置为sizeof(structsockaddr)。

structsockaddr结构类型是用来保存Socket信息的:

structsockaddr

{

unsignedshortsa_family;/*地址族,AF_xxx*/

charsa_data[14];/*14字节的协议地址*/

};

sa_family一般为AF_INET,代表Internet(TCP/IP)地址族;sa_data则包含该Socket的IP地址和端口号。

另外还有一种结构类型:

structsockaddr_in

{

shortintsin_family;/*地址族*/

unsignedshortintsin_port;/*端口号*/

structin_addrsin_addr;/*IP地址*/

unsignedcharsin_zero[8];/*填充0以保持与structsockaddr同样大小*/

};

这个结构更方便使用。

sin_zero用来将sockaddr_in结构填充到与structsockaddr同样的长度,可以用bzero()或memset()函数将其置为零。

指向sockaddr_in的指针和指向sockaddr的指针可以相互转换,这意味着如果一个函数所需参数类型是sockaddr时,你可以在函数调用的时候将一个指向sockaddr_in的指针转换为指向sockaddr的指针;或者相反。

使用bind函数时,可以用下面的赋值实现自动获得本机IP地址和随机获取一个没有被占用的端口号:

my_addr.sin_port=0;/*系统随机选择一个未被使用的端口号*/

my_addr.sin_addr.s_addr=INADDR_ANY;/*填入本机IP地址*/

通过将my_addr.sin_port置为0,函数会自动为你选择一个未占用的端口来使用。

同样,通过将my_addr.sin_addr.s_addr置为INADDR_ANY,系统会自动填入本机IP地址。

注意在使用bind函数是需要将sin_port和sin_addr转换成为网络字节优先顺序;而sin_addr则不需要转换。

面向连接的客户程序使用Connect函数来配置Socket并与远端服务器建立一个TCP连接,其函数原型为:

intconnect(intsockfd,structsockaddr*serv_addr,intaddrlen);

Sockfd是Socket函数返回的Socket描述符;serv_addr是包含远端主机IP地址和端口号的指针;addrlen是远端地质结构的长度。

Connect函数在出现错误时返回-1,并且设置errno为相应的错误码。

进行客户端程序设计无需调用bind(),因为这种情况下只需知道目的机器的IP地址,而客户通过哪个端口与服务器建立连接并不需要关心,Socket执行体为你的程序自动选择一个未被占用的端口,并通知你的程序数据什么时候到打断口。

Connect函数启动和远端主机的直接连接。

只有面向连接的客户程序使用Socket时才需要将此Socket与远端主机相连。

无连接协议从不建立直接连接。

面向连接的服务器也从不启动一个连接,它只是被动的在协议端口监听客户的请求。

Listen函数使Socket处于被动的监听模式,并为该Socket建立一个输入数据队列,将到达的服务请求保存在此队列中,直到程序处理它们。

intlisten(intsockfd,intbacklog);

Sockfd是Socket系统调用返回的Socket描述符;backlog指定在请求队列中允许的最大请求数,进入的连接请求将在队列中等待accept()它们。

Backlog对队列中等待服务的请求的数目进行了限制,大多数系统缺省值为20。

如果一个服务请求到来时,输入队列已满,该Socket将拒绝连接请求,客户将收到一个出错信息。

当出现错误时listen函数返回-1,并置相应的errno错误码。

accept()函数让服务器接收客户的连接请求。

在建立好输入队列后,服务器就调用accept函数,然后睡眠并等待客户的连接请求。

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

sockfd是被监听的Socket描述符,addr通常是一个指向sockaddr_in变量的指针,该变量用来存放提出连接请求服务的主机的信息(某台主机从某个端口发出该请求);addrten通常为一个指向值为sizeof(structsockaddr_in)的整型指针变量。

出现错误时accept函数返回-1并置相应的errno值。

首先,当accept函数监视的Socket收到连接请求时,Socket执行体将建立一个新的Socket,执行体将这个新Socket和请求连接进程的地址联系起来,收到服务请求的初始Socket仍可以继续在以前的Socket上监听,同时可以在新的Socket描述符上进行数据传输操作。

数据传输

Send()和recv()这两个函数用于面向连接的Socket上进行数据传输。

Send()函数原型为:

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

Sockfd是你想用来传输数据的Socket描述符;msg是一个指向要发送数据的指针;Len是以字节为单位的数据的长度;flags一般情况下置为0。

recv()函数原型为:

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

Sockfd是接受数据的Socket描述符;buf是存放接收数据的缓冲区;len是缓冲的长度。

Flags也被置为0。

Recv()返回实际上接收的字节数,当出现错误时,返回-1并置相应的errno值。

如果你对数据报Socket调用了connect()函数时,你也可以利用send()和recv()进行数据传输,但该Socket仍然是数据报Socket,并且利用传输层的UDP服务。

但在发送或接收数据报时,内核会自动为之加上目地和源地址信息。

结束传输:

当所有的数据操作结束以后,你可以调用close()函数来释放该Socket,从而停止在该Socket上的任何数据操作:

close(sockfd);

(1)服务器端代码分析

服务器端一直在监听是否有客户端连接,如有连接,处理客户端的请求,给出回应,然后继续监听。

因为IP地址,端口号等信息需要自己输入,所以main函数需要参数。

intmain(intargc,char**argv)

将第一个输入的字符串参数转化为整形数后,作为端口号赋值给myport,默认参数为7838

if(argv[2])myport=atoi(argv[2]);

elsemyport=7838;

printf("Portisok!

\n");

创建Socket,如果返回值为-1,则创建成功,否则创建失败

if((sockfd=Socket(PF_INET,SOCK_STREAM,0))==-1)

{printf("CreatSocketsucceed!

\n");

perror("Socket");

exit

(1);}

else

printf("CreatSocketfailed!

\n");

将my_addr空间清空,且包括“、0”

bzero(&my_addr,sizeof(my_addr));

设置地址族

my_addr.sin_family=PF_INET;

设置端口号,以大端方式赋值(htons():

把16位值从主机字节序转换成网络字节序)

my_addr.sin_port=htons(myport);

设置IP地址,将IP地址字符参数3,转换为32位网络序列的IP地址,如果没有参数3,则自动填入本机IP地址

if(argv[3])

my_addr.sin_addr.s_addr=inet_addr(argv[1]);

else

my_addr.sin_addr.s_addr=INADDR_ANY;

printf("SetIPsucceed!

\n");

调用bind函数将其与本机地址以及一个本地端口号绑定

if(bind(sockfd,(structsockaddr*)&my_addr,sizeof(structsockaddr))==-1)

{

printf("Failtobind!

\n");

perror("bind");

exit

(1);

}

printf("Succeedtobind!

\n");

下面是收发程序的主体,为了实现循环收发,使用了while死循环,需要断开时按ctrl+C

charrecv[30];

char*send=“hello,thisisserver!

”;

while

(1)

{

memset(recv,0,sizeof(recv));

recvfrom(sockfd,recv,sizeof(recv),0,(structsockaddr*)&client_addr,&addr_len);

printf(“%s\n”,recv);

sendto(sockfd,send,strlen(send),0,(structsockaddr*)&client_addr,&addr_len);

}

关闭Socket,返回

close(sockfd);

return0;

(2)客户端代码分析

因为IP地址,端口号等信息需要自己输入,所以main函数需要参数

intmain(intargc,char**argv)

如果输入参数不够,则退出

if(argc!

=3)

{

printf("Peremetererro!

Forexample:

\n\t\t%sIPport\n\t:

\t%s127.0.0.180\n",argv[0],argv[0]);

exit(0);

}

elseprintf("\nProgramstartsnormally!

\n");

创建一个Socket用于tcp通信

if((sockfd=Socket(AF_INET,SOCK_STREAM,0))<0)

{

printf("FailtocreatSocket!

\n");

perror("Socket");

exit(errno);

}

elseprintf("CreatSocketsucceed!

\n");

初始化服务器端(对方)的地址和端口信息

bzero(&dest,sizeof(dest));

dest.sin_family=AF_INET;

dest.sin_port=htons(atoi(argv[2]));

if(inet_aton(argv[1],(structin_addr*)&dest.sin_addr.s_addr)==0)

{

printf("Failtoinitialipaddressandport!

\n");

perror(argv[1]);

exit(errno);

}

elseprintf("Initialipaddressandportsucceed!

\n");

连接服务器

printf("\nConnecting......\n");

connum=connect(sockfd,(structsockaddr*)&dest,sizeof(dest));

printf("Connectfailbecasueof%d%d\n",connum,errno);

if(connum!

=0)

{

printf("Connectfail!

\n");

perror("Connect");

exit(errno);

}

elseprintf("Connectsucceed!

\n");

printf("\nEverything

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

当前位置:首页 > 党团工作 > 入党转正申请

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

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