本文主要是介绍【TINY4412】嵌入式Linux网络编程,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
主要步骤
- BOA移植
- 在页面上配置开发板参数
- 用TCP传输文件
- 参考资料
BOA移植
-
下载BOA并解压
-
安装bison和flex
sudo apt-get install bison
sudo apt-get install flex
- 修改src/compat.h
找到
#define TIMEZONE_OFFSET(foo) foo##->tm_gmtoff
修改成
#define TIMEZONE_OFFSET(foo) (foo)->tm_gmtoff
否则会出现错误:
util.c:100 :1: error: pasting “t” and “->” does not give a valid preprocessing token make: *** [util.o] 错误 1
- 修改 src/log.c
注释掉:
/*if (dup2(error_log, STDERR_FILENO) == -1) {DIE("unable to dup2 the error log");
}*/
否则会出现错误:
log.c:73 unable to dup2 the error log:bad file descriptor
- 修改src/boa.c
注释掉:
/*if (passwdbuf == NULL) {DIE(”getpwuid”);
}
if (initgroups(passwdbuf->pw_name, passwdbuf->pw_gid) == -1) {DIE(”initgroups”);
}*/
否则会出现错误:boa.c:211 - getpwuid: No such file or directory
注释掉:
/*if (setuid(0) != -1) {DIE(”icky Linux kernel bug!”);
}*/
否则会出现问题:boa.c:228 - icky Linux kernel bug!: No such file or directory
- 生成Makefile文件
cd boa-0.94.13/src
./configure
- 修改Makefile
cd src
vim Makefile
修改CC = gcc 为 CC = arm-linux-gcc
修改CPP = gcc -E 为 CC = arm-linux-gcc –E
- 编译
make
将调试信息剥去,减小二进制文件boa的大小:
arm-linux-strip boa
- BOA的配置
(1)Group、User的修改
(2)ScriptAlias的修改
(3)ServerName的设置
修改 #ServerName www.your.org.here 为 ServerName www.your.org.here
否则会出现错误“gethostbyname::No such file or directory”,开不了boa服务器
(4)AccessLog修改
修改 AccessLog /var/log/boa/access_log 为 #AccessLog /var/log/boa/access_log
否则会出现错误提示:“unable to dup2 the error log: Bad file descriptor”
(5)建立相关文件夹
(a)在开发板上创建目录 /etc/boa 并且把boa.conf拷贝到这个目录下:
mkdir /etc/boa
sudo minicom –s # 设置Filenames and paths
发送刚配置的发送文件路径下的文件:
Ctrl + A,再按S ,在弹出窗口里选择zmodem,然后在弹出的窗口里选择要发送的文件,上下键移动,空格键选定,回车键发送
(b)将boa传到 /bin 目录下
(c)创建HTML文档的主目录,存放相应的页面即html文件
mkdir /var/www
(d)
mkdir /var/www/cgi-bin # 用来放CGI脚本
(e)创建日志文件所在目录:
mkdir /var/log/boa
在运行时会产生access_log 和error_log两个文件,errr_log会打印出boa运行时所产生的错误信息
(f)将主机/etc/mime.types 传到到开发板 /etc 目录下
- 运行BOA
/bin/boa
如果提示boa.c:194 - unable to bind: Address already in use ,那是因为当前文件系统中有一个boa服务器,ps找到这个程序的序号,然后kill掉,再运行boa服务器就行了,到此boa服务器搭建成功。
- 测试BOA
(1)在 /var/www/ 文件夹内放入index.html文件
(2)
ifconfig # 查看开发板ip
(3)更改主机ip和网关,使其与开发板处于同一网段
(4)ping
(5)在浏览器中输入http://192.168.1.230
在页面上配置开发板参数
- 设置网络访问页面
(1)index.html文件
(2)将index.html保存至根文件系统 /var/www/ 文件夹中
(3)在浏览器中访问http://192.168.1.230
- 编写cgi_conf.c文件
(1)采用GET方式传输信息,环境变量值为:QUERY_STRING。当我将表单的数据提交时,客户机会将这些数据添加到action标记命名的URL结尾,并用?将cgi的程序与表单提交的信息分隔开。
(2)CGI程序从客户端获取环境变量后,需要进行解码,这里我们采用sscanf( )函数来进行URL解码,即分离变量的值。
(3)CGI标准规定了CGI程序可以使用的三个HTTP标题。标题必须占据第一行输出,而且必须随后带有一个空行。
(4)通过修改/etc/eth0-setting文件来配置IP地址、netmask、gateway。
- 交叉编译cgi_conf.cgi可执行文件
保存文件至根文件系统 /var/www/cgi-bin 文件夹中
arm-linux-gcc -o cgi_conf.cgi cgi_conf.c
-
创建 /var/log/boa 目录
-
运行BOA
(1)
/bin/boa
(2)在浏览器中输入http://192.168.1.230
- 重启后配置生效
用TCP传输文件
- Linux网络编程基础
(1)嵌套字
多个TCP连接或者多个应用程序进程可能需要同一个TCP端口传输数据。为了区分不同应用程序进程和连接,许多计算机操作系统为应用程序与TCP/IP交互提供了称为嵌套字(Socket)的接口。常用的TCP/IP有以下三种类型的嵌套字:
(a)流式嵌套字(SOCK_STREAM)
用于提供面向连接的、可靠的数据传输服务,即使用TCP进行传输。
(b)数据报嵌套字(SOCK_DGRAM)
用于提供无连接的服务,即使用UDP进行传输。
(c)原始嵌套字(SOCK_RAW)
可以读写内核没有处理的IP数据报,而流式嵌套字只能读取TCP的数据,数据报嵌套字只能读取UDP的数据。
(2)端口
TCP/IP协议中的端口,端口号的范围从065535。端口一类是由互联网指派名字和号码公司ICANN负责分配给一些常用的应用程序固定使用的“周知的端口”,其值一般为01023。例如http的端口号是80,FTP为21,SSH为22,Telnet为23等。还有一类是用户自己定义的,通常是大于1024的整型值。
(3)网络地址
网络通信,归根到底还是进程间的通信(不同计算机上的进程间通信)。在网络中,每一个节点(计算机或路由)都有一个网络地址,如192.168.1.4,也就是IP地址。两个进程通信时,首先要确定各自所在的网络节点的网络地址。
但是,网络地址只能确定进程所在的计算机,而一台计算机上很可能同时运行着多个进程,所以仅凭网络地址还不能确定到底是和网络中的哪一个进程进行通信,因此套接口中还需要包括其他的信息,也就是端口号(PORT)。所以,使用端口号和网络地址的组合可以唯一的确定整个网络中的一个网络进程。
例如,如网络中某一台计算机的IP为192.168.1.4,操作系统分配给计算机中某一应用程序进程的端口号为1500,则此时192.168.1.4 1500就构成了一个套接口。
(4)字节序
不同的CPU采用对变量的字节存储顺序可能不同。常用的X86结构是小端模式,很多的ARM,DSP都为小端模式,即内存的低地址存储数据的低字节,高地址存储数据的高字节。而KEIL C51则为大端模式,内存的高地址存储数据的低字节,低地址存储数据高字节。对于网络传输来说,数据顺序必须是一致的,网络字节顺序采用大端字节序方式。
- TCP
(1)服务器端
(a)创建socket
Socket就是一种文件描述符,和普通的打开文件一样,需要检测其返回结果。
函数格式:int socket(int domain, int type, int protocol);
(b)设置socket:设置何种协议族,设置本机IP和端口,也就有了唯一性。
(c)绑定socket:把套接字绑定到本地计算机的某一个端口上。
函数格式:int bind(int sockfd, struct sockaddr *addr, int addrlen);
(d)开始监听:使服务器的这个端口和IP处于监听状态,等待网络中某一客户机的连接请求。
函数格式:int listen(int sockfd, int backlog);
(e)阻塞,等待连接:接受连接请求,建立起与客户机之间的通信连接。
函数格式:int accept(int sockfd, struct sockaddr *addr, int *addrlen);
(f)接收数据:用新的套接字来接收远端主机传来的数据,并把数据存到由参数buf指向的内存空间。
(g)关闭socket。
(2)客户机端
(a)创建socket
(b)设置socket
(c)连接:用来请求连接远程服务器,将参数sockfd的socket连至参数serv_addr所指定的服务器IP和端口号上去。
函数格式:int connect (int sockfd, struct sockaddr *serv_addr, int addrlen);
(d)关闭socket。
- 编译.c文件
(1)交叉编译server.c
arm-linux-gcc –o server server.c
(2)编译client.c
gcc –o client client.c
-
用minicom传输server到开发板上
-
运行可执行文件
(1)运行server:
./server
(2)运行client:
./client
(a)输入list:服务器将当前文件名发送回客户端;
(b)输入get+文件名: 下载文件至客户端;
(c)输入put+文件名:上传文件至服务器。
参考资料
https://www.cnblogs.com/javawebsoa/archive/2013/08/01/3230930.html
https://blog.csdn.net/u010841212/article/details/44732549
https://www.cnblogs.com/chent/p/4209174.html
https://blog.csdn.net/wan_exe/article/details/77428460
https://www.cnblogs.com/rwzhou/p/3649475.html
https://blog.csdn.net/mashang123456789/article/details/22846551
https://blog.csdn.net/usernamecontroled/article/details/22865095
https://hceng.cn/2017/12/30/嵌入式Linux网络编程——TCP_UDP/
https://blog.csdn.net/jishuqianjia/article/details/80004452
https://blog.csdn.net/ce123_zhouwei/article/details/12769789
https://blog.csdn.net/ce123_zhouwei/article/details/13287341
https://blog.csdn.net/qq_37689106/article/details/83997667
这篇关于【TINY4412】嵌入式Linux网络编程的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!