首页
AI
爬虫
爬虫案例
JS逆向技巧
APP逆向
嵌入式开发
C语言入门视频教程
模电数电
51/52单片机
STM32
Linux嵌入式
文学修养
感动和励志文字
生活哲理
随手乱写
IT计算机
QT学习之路
数据库设计
网站搭建
微信开发
Java
计算机知识
NCRE全国计算机等级考试
编程语言
Web程序设计
关于我们
广告招租
表白网页制作
搜索
登录
搜索
RainFly
明确一个目标,这很重要!
累计撰写
215
篇文章
累计收到
4779
条评论
首页
栏目
首页
AI
爬虫
爬虫案例
JS逆向技巧
APP逆向
嵌入式开发
C语言入门视频教程
模电数电
51/52单片机
STM32
Linux嵌入式
文学修养
感动和励志文字
生活哲理
随手乱写
IT计算机
QT学习之路
数据库设计
网站搭建
微信开发
Java
计算机知识
NCRE全国计算机等级考试
编程语言
Web程序设计
关于我们
广告招租
表白网页制作
嵌入式开发
2017-10-14
Ubuntu14.04安装配置mosquito及websocket启用。
设计思路:利用MQTT协议 实现底层硬件和web实时双向通讯。 mosquito:http://mosquitto.org/files/source/ libwebsockets:https://gitee.com/woniu201/libwebsockets 安装步骤: 1.下载并编译liewevsocket $ tar zxvf libwebsockets-1.4-chrome43-firefox-36.tar.gz $ cd libwebsockets-1.4-chrome43-firefox-36 $ mkdir build $ cd build $ cmake ..(PS:apt-get install cmake 安装cmake工具) $ make install $ ldconfig 2.编译安装mosquito $ wget http://mosquitto.org/files/source/mosquitto-1.4.2.tar.gz $ tar zxvf mosquitto-1.4.2.tar.gz $ cd mosquitto-1.4.2 更改configure.mk中 WITH_WEBSOCKETS:=no 变成(这一步是做WebSocket支持) WITH_WEBSOCKETS:=yes $ make $ make install $ cp mosquitto.conf /etc/mosquitto 编译过程可能遇到一些错误, 解决编译过程中找不到ares.h的问题:HTTP://www.cnblogs.com/xiaoerhei/p/3777157.html mosquitoo 默认的端口是1883 websockets默认是9001 请在/etc/mosquitto/mosquitto.conf 的“Default Listener” 一节添加如下几行: port 1883 listener 9001 protocol websockets 但是在阿里云ECS主机后台需要配置开放端口,9001端口无法开启,配置为1884. 3.添加用户且重新启动进程 $ adduser mosquitto $ reboot //重新启动进程 $ mosquitto -c /etc/mosquitto/mosquitto.conf -d 查看所有端口是否已经打开 netstat -anp 测试可以正常访问的!
2017年-10月-14日
11916 阅读
6 评论
Linux嵌入式
2017-9-1
Linux Web服务器和下位机TCP交互(Socket多线程编程)
由于多个项目需求(关于云服务器云支付等方式触发远程设备响应),之前使用过HTTPSQL轮询法,希望通过此种方法实现底层和云服务器数据交互,且大量占用服务器,只需要保持TCP连接。服务器始终保留其线程; 使用工具 HTOP 进程管理工具。(支持鼠标操作) 关于 HTOP使用方法: 百度 思路:通过linux网络编程,实现服务器和客户端一直保持连接,且服务器保留客户端唯一ID 和动态的socketfd {中转服务器有一个map表,客户名+socket} 如果下位机有主动事件,则通过TCP协议将数据发送给终端处理 或者通过HTTP协议将数据提交到web服务器来处理 若服务器有主动事件,只可以通过TCP协议将指定数据发送到指定的ID中 (通过socketfd)(难点:ID和socketfd需要对应且动态变化(重启或者意外事件)) 可以通过一个内存缓存区来存放 ID和socketfd; (如果利用内存缓冲区存放,若web服务器无法获得socket) 通过数据库存放; 使用linux C访问数据库 需要安装一个特定的包 sudo apt-get install libmysqlclient15-dev
2017年-9月-1日
8844 阅读
8 评论
Linux嵌入式
2017-8-17
IC卡系统研究
最近项目上面需要用到刷卡系统,继而研究了一下对IC 相关的资料进行学习 项目平台 Windows 10 刷卡器 ZLG600A-T2 V1.03 上位机 QT4.8和zlg调试工具 IC卡 S50普通白卡 普通S50 IC卡存储结构: MF1 卡分为 16 个扇区,每区有 4 块(块 0~块 3),共 64 块,按块号编址为 0~63。第 0 扇区的块 0(即 绝对地址块 0)用于存放芯片商,卡商相关代码,已经固化不可更改。其他各扇区的块 0,块 1,块 2 为数 据块,用于存贮用户数据;块 3 为各扇区控制块,用于存放密码 A,存取控制条件设置,密码 B。各区控 制块结构相同,具体如下图所示: 如果需要对其IC进行读写就需要验证秘钥AB,验证完成后可以对数据块(0~63块)进行任意读写 每个块拥有 16个字节空间,16x64=1024Bytes= 1K Bytes 即 容量为 8K 位 EEPROM; 注意:密码验证正确后,直接往第三区写数据就可以了,可以修改整个扇区的秘钥A,控制位,秘钥B, 注意控制位,因为控制位代表了新密码的权限及对数据位的控制,如果写入进去后就会把卡锁死了! 控制位 FF 07 80 69 参考文档 http://pan.baidu.com/s/1o85Id1C
2017年-8月-17日
9626 阅读
6 评论
Linux嵌入式
2017-7-28
快速将VIM打造成IDE工具
SUPER TAB 工具 从http://www.vim.org/scripts/script.php?script_id=1643下载安装版。这个安装包跟先前的几个Vim插件不同,它是一个vba文件,即Vimball格式的安装包,这种格式安装包提供傻瓜式的安装插件的方法。 1)用Vim打开.vba安装包文件。 2)在Vim命令行下运行命令“UseVimball ~/.vim”。此命令将安装包解压缩到~/.vim目录。VImball安装方式的便利之处在于你可以在任何目录打开.vba包安装,而不用切换到安装目的地目录。而且不用运行helptags命令安装帮助文档。 3)在~/.vimrc文件中加入以下这行: let g:SuperTabDefaultCompletionType="context" CTAGS http://www.cnblogs.com/willsonli/p/6555179.html
2017年-7月-28日
8350 阅读
1 评论
Linux嵌入式
2017-7-21
实现ESP8266模块同远程web服务器交互请求
实验材料: 1.ESP 8266模块 2 有公网IPv4的web服务器(当然也可以通过域名访问,这里先测试通过IP地址建立TCP连接) 实验原理: 原理很简单,通过串口向ESP8266发送一系列指令,由于8266内置了TCP协议栈,我们只需要通过指令建立TCP连接,当连接建立完成后,直接发送GET/POST请求,接受到web服务器传输过来的数据链接,通过这些交互数据分析,从而实现开发板和web服务器之间的数据互换。 步骤: 1. 配置ESP为站点模式,连接到可以正常访问英特网的热点上面。 2. 配置模块为透传模式 3.建立TCP连接 IP 端口号等 4直接发送 请求查看串口返回的参数值 GET /index.html HTTP/1.1 (TCP请求可以加密) 注意事项 测试的时候 发送指令总是回复400 错误,经过查找发现由于协议中回车换行为加上引起无法提交POST请求 POST /1.php HTTP/1.1\r\nHost: 192.168.0.107\r\nConnection: keep-alive\r\nContent-Length: 34\r\nContent-Type: application/x-www-form-urlencoded\r\n\r\nfirstname=hello&lastname=123&age=123\r\n <html> <body> <form action="" method="post"> Firstname: <input type="text" name="firstname" /> Lastname: <input type="text" name="lastname" /> Age: <input type="text" name="age" /> <input type="submit" /> </form> </body> </html> <?php $con = mysql_connect("localhost","root","root"); if (!$con) { die('Could not connect: ' . mysql_error()); } mysql_select_db("test", $con); $sql="INSERT INTO Persons (FirstName, LastName, Age) VALUES ('$_POST[firstname]','$_POST[lastname]','$_POST[age]')"; if (!mysql_query($sql,$con)) { die('Error: ' . mysql_error()); } echo "1 record added"; mysql_close($con) ?> 由于是网络配置器 所以发送的数据很正常,但是通过wifi串口发送的时候 /r/n会由于ascii编码 而不是回车 继而串口发送总是失败,我利用ASCII码转HEX工具将 所有发送文件转为十六进制 然后通过十六进制 进行串口数据发送 至此通过串口芯片发送POST请求到指定云服务,实例完成。以下提供所用到的软件 软件压缩包来源:百度网盘 | 大小:MB | 提取密码: | 解压密码:www.rainfly.cn 已经过安全软件检测无毒,请您放心下载。 若链接失效可联系管理员!
2017年-7月-21日
13076 阅读
7 评论
Linux嵌入式
2017-7-5
STM32F107VC互联型芯片建立Keil5工程
使用STM32F107VC芯片配置工程的时候,出现一些报错,继而写此文档。 建立三个文件夹 文件夹CORE内包含 FW 是官方提供固件库 USER 是编译的主文件,和一些重要文件 建立keil 5工程 添加两个宏和头文件 运行后基本上没有错误和警告了, 注意事项: 1. .s启动文件选择 2.宏定义的选择 选择的文件是 startup_stm32f10x_cl.s 和 STM32F10X_CL
2017年-7月-5日
6658 阅读
5 评论
STM32
2017-6-28
STM32学习笔记之IIC总线
基于对STM32F103的手册可以看出来,具备两路IIC总线端口,其实我们不使用系统提供的IIC硬件,通过做成普通IO口来模拟ICC总线,完成对IIC总线的了解和学习。 首先是对IIC总线的工作原理进行了解: IIC系统由一条串行数据线SDA和一条串行时钟线SCL组成。主机按一定的通信协议向从机寻址和进行信息 传输。在数据传输时,由主机初始化一次数据传输,主机使数据在SDA线上传输的同时还通过SCL线传输时钟。信息传输的对象和方向以及信息传输的开始和终 止均由主机决定。 每个器件都有一个唯一的地址,而且可以是单接收的器件(例如:LCD驱动器)或者可以接收也可以发送的器件(例如:存储器)。发送器或接收器可以在主模式或从模式下操作,这取决于芯片是否必须启动数据的传输还是仅仅被寻址。 //初始化IIC void IIC_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE ); //GPIOB时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_11; 配置IIC引脚 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_SetBits(GPIOB,GPIO_Pin_10|GPIO_Pin_11); } 通过对PB10 PB11配置IO来做成对其初始化要求。 开始信号:SCL为高电平时,SDA由高电平向低电平跳变,开始传送数据。 结束信号:SCL为高电平时,SDA由低电平向高电平跳变,结束传送数据。 应答信号:接收数据的IC在接收到8bit数据后,向发送数据的IC发出特定的低电平脉冲,表示已收到数据。CPU向受控单元发出一个信号后,等待受控单元发出一个应答信号,CPU接收到应答信号后,根据实际情况作出是否继续传递信号的判断。若未收到应答信号,由判断为受控单元出现故障。 //启动IIC void IIC_Start(void) { SDA_OUT(); IIC_SDA=1; //将SDA和SCL都拉置高电平,然后进行一定的延时 IIC_SCL=1; delay_us(4); IIC_SDA=0;//START:when CLK is high,DATA change form high to low delay_us(4); //SDA产生由高电平向低电平的跳变的时候,从而产生一个启动信号 IIC_SCL=0; //锁住IIC总线 } //终止信号 void IIC_Stop(void) { SDA_OUT(); IIC_SCL=0; IIC_SDA=0;//STOP:when CLK is high DATA change form low to high delay_us(4); IIC_SCL=1; IIC_SDA=1; //发送iic终止信号 delay_us(4); //延时产生一个控制信号 }
2017年-6月-28日
9527 阅读
1 评论
STM32
2017-6-19
STM32学习笔记1之通用GPIO
开篇: 已经很久未更新相关内容,由于工作原因,开始学习STM32,会将学习和工作遇到的任何问题和进展,都写下来,如果需要的伙伴可以加上书签在下面留言给我,共同探讨进步。 学习平台: 芯片:STM32F10x 库函数版本:V3.5.0 开发板:百为 由于需要马上上手,继而对于底层寄存器操作认识先行搁置,只要是已开发为主,所以采用官方提供的API接口 通过这些接口来实现对STM3210X的软件编写, 官方提供的固件库 :http://pan.baidu.com/s/1bp6bgcf GPIO的函数和变量 GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //LED0-->PB.5 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; typedef struct { uint16_t GPIO_Pin; /*!< Specifies the GPIO pins to be configured. //0-15对应的管脚号 This parameter can be any value of @ref GPIO_pins_define */ GPIOSpeed_TypeDef GPIO_Speed; /*!< Specifies the speed for the selected pins. //io口传输频率 This parameter can be a value of @ref GPIOSpeed_TypeDef */ GPIOMode_TypeDef GPIO_Mode; /*!< Specifies the operating mode for the selected pins. 选择输入或输出且是否其他功能 This parameter can be a value of @ref GPIOMode_TypeDef */ }GPIO_InitTypeDef; #define GPIO_Pin_0 ((uint16_t)0x0001) /*!< Pin 0 selected */ #define GPIO_Pin_1 ((uint16_t)0x0002) /*!< Pin 1 selected */ #define GPIO_Pin_2 ((uint16_t)0x0004) /*!< Pin 2 selected */ #define GPIO_Pin_3 ((uint16_t)0x0008) /*!< Pin 3 selected */ #define GPIO_Pin_4 ((uint16_t)0x0010) /*!< Pin 4 selected */ #define GPIO_Pin_5 ((uint16_t)0x0020) /*!< Pin 5 selected */ #define GPIO_Pin_6 ((uint16_t)0x0040) /*!< Pin 6 selected */ #define GPIO_Pin_7 ((uint16_t)0x0080) /*!< Pin 7 selected */ #define GPIO_Pin_8 ((uint16_t)0x0100) /*!< Pin 8 selected */ #define GPIO_Pin_9 ((uint16_t)0x0200) /*!< Pin 9 selected */ #define GPIO_Pin_10 ((uint16_t)0x0400) /*!< Pin 10 selected */ #define GPIO_Pin_11 ((uint16_t)0x0800) /*!< Pin 11 selected */ #define GPIO_Pin_12 ((uint16_t)0x1000) /*!< Pin 12 selected */ #define GPIO_Pin_13 ((uint16_t)0x2000) /*!< Pin 13 selected */ #define GPIO_Pin_14 ((uint16_t)0x4000) /*!< Pin 14 selected */ #define GPIO_Pin_15 ((uint16_t)0x8000) /*!< Pin 15 selected */ #define GPIO_Pin_All ((uint16_t)0xFFFF) /*!< All pins selected */ typedef enum { GPIO_Speed_10MHz = 1, //选择传输MHz GPIO_Speed_2MHz, GPIO_Speed_50MHz }GPIOSpeed_TypeDef; typedef enum { GPIO_Mode_AIN = 0x0, GPIO_Mode_IN_FLOATING = 0x04, GPIO_Mode_IPD = 0x28, GPIO_Mode_IPU = 0x48, GPIO_Mode_Out_OD = 0x14, GPIO_Mode_Out_PP = 0x10, GPIO_Mode_AF_OD = 0x1C, GPIO_Mode_AF_PP = 0x18 }GPIOMode_TypeDef; GPIO_Init(GPIOB, &GPIO_InitStructure); //设置GPIOB为初始化的IO引脚,且将GPIO_IniStructure对应刚才设置的结构体 指针所包含的 PIN SPEED MODE)初始化 GPIO_SetBits(GPIOB,GPIO_Pin_5);//置1 GPIO_ResetBits(GPIOB,GPIO_Pin_5); //清0 还有很多复用功能,继续添加
2017年-6月-19日
8104 阅读
5 评论
STM32
2016-8-24
ARM9与远程web服务器交互之灯控实验
摘要:网上又不少历程关于ARM平台的web实验,基本上都是在内网完成的,本地搭建好web服务器,而ARM平台的web服务器不支持内网穿透,继而无法从外网访问控制,或许你有公网IP可以进行端口映射访问,不过本次实验目的不在此,本次主要完成ARM9开发板通过HTTP协议与Apache服务器数据交互。如有错误或者建议,敬请批评指正。 实验设备: EasyARM i.mx283(周立功ARM9板子) linux2.6.35系统 ECS云服务器 具备公网IP 120.27.4.152 (ubunut14.04系统 Apache2+PHP5+MySQL) 配置方法 —>点此 交叉编译工具 arm-none-linux-gnueabi-gcc 宿主机 Ubuntu14.04 语言需求:C ,HTML,JavaScript,jquery,PHP,MySQL,shell脚本(了解) 实验原理: 通过ARM开发板不断向web服务器发送POST/GET请求,来获得服务器返回的数据,数据中携带了light0的value值,通过C对字符串分析获得服务器数据库类light0的value值,来更改P2.4引脚的电平高低,从而达到下位机控灯,至于web页面通过ajax GET方式提交至相应PHP文件,从而修改数据库类light0 的value值。完成web服务器控灯实验 开发板方面不做过多介绍,周立功官网上面提供了手册, 提一下重要操作就是关于灯控的高低点平,/sys/class/gpio/在这个类下面(GPIO驱动已经提供了,先拿来用) 我们按照手册上面所提供的数据建立好一个 68 P2.4引脚的虚拟控制文件, (linux下面一切皆为文件),生成了引脚电平控制文件 /sys/devices/virtual/gpio/gpio68/value 通过echo 1(0) > value 可以更改P2.4引脚高低电平。 C语言文件 #include<stdio.h> #include<stdlib.h> #include<string.h> #include<sys/types.h> #include<sys/socket.h> #include<arpa/inet.h> #include<string.h> #include<fcntl.h> #include<unistd.h> #define IP_ADDR "120.27.4.152" #define ARCHIVE "/data/light.php" #define PORT 80 #define DEV_PATH "/sys/devices/virtual/gpio/gpio68/value" #define HIGH "1" #define LOW "0" int main(int argc, char *argv[]){ int fd; int sockfd; int len; struct sockaddr_in address; int result; char data[1024]; memset(data, 'a', 1024); char httpstring[2048]; sprintf(httpstring,"POST /%s HTTP/1.1\r\n" "Host: %s\r\n" "Content-Length: %d\r\n" "Connection:Close\r\n\r\n" "Content-Type: Application/octet-stream\r\n\r\n" "$name=rainfly" "%s", ARCHIVE, IP_ADDR, strlen(data), data); char ch; sockfd = socket(AF_INET, SOCK_STREAM, 0); address.sin_family = AF_INET; address.sin_addr.s_addr = inet_addr(IP_ADDR); address.sin_port = htons(PORT); len = sizeof(address); result = connect(sockfd,(struct sockaddr *)&address,len); if(result == -1) { perror("oops: client"); return 1; } write(sockfd,httpstring,strlen(httpstring)); while(read(sockfd,&ch,1)) { // printf("%c", ch); } // printf("%c",ch); int a= ch-48;//ASCII change // printf("%d",a); if(a==1) { printf("open"); fd=open(DEV_PATH,O_WRONLY); if(fd<0){printf("open value fail!");} write(fd,HIGH,strlen(HIGH)); close(fd); } else{ printf("close"); fd=open(DEV_PATH,O_WRONLY); if(fd<0){printf("open value fail!");} write(fd,LOW,strlen(LOW)); close(fd); } close(sockfd); printf("\n"); return 0; } 注意: 不管data的数据内容是什么上面我发送的是1024个'a' 虽然这毫无用出,关于这个POST GET提交方式,在本次实验都是可以的携带的data数据并没有实质性作用,(PS:或许在以后的实验中,需要用到数据提交给服务器)。这里仅实现对服务器发送POST请求,然后通过服务器判断是否携带了数据参数来进行输出,或者修改数据库 核心PHP脚本。 /data/light.php <?PHP $lnk = mysql_connect("127.0.0.1:3306","root","Dyf1314520"); if (!$lnk){ die('Could not connect: ' . mysql_error()); } if(mysql_query("CREATE DATABASE smarthome",$lnk)){ mysql_select_db('smarthome', $lnk); $sql = "CREATE TABLE light ( LightName varchar(7), value int )"; mysql_query($sql,$lnk);//创建表结构 mysql_query("INSERT INTO light (LightName, value) VALUES ('light0', '1')"); //插入新表项 } mysql_select_db('smarthome', $lnk); //选中数据库 //带参数访问更改 数据库中 light0的值 if (isset($_GET['light0'])) { $light0=$_GET['light0']; mysql_query("UPDATE light SET value = ".$light0." WHERE LightName = 'light0'"); echo $light0; } else { //如果直接访问就获得数据库数据 $result = mysql_query("SELECT * FROM light WHERE LightName='light0'"); //mysql系的函数中都是逐行读取的,即第一次mysql_fetch_array得到第一行,第二次得到第二行 //实际上一个灯只需要第一行 while($row = mysql_fetch_array($result)) { echo $row['value']; } } ?> 该文件既处理Ajax提交过来的GET请求,将数据库中light0 的value值进行修改,也应答下位机POST请求,将value值通过HTTP协议发送给下位机。 home_light.php 页面AJAX提交源码 //去除str的前后空格 function trim(str){ return str.replace(/^(\s|\u00A0)+/,'').replace(/(\s|\u00A0)+$/,''); } var light0_temp=1; var light0; $(document).ready(function(){ $("#light0").click(function(){ light0_temp = ~ light0_temp; if(light0_temp!='1'){light0=0;} else {light0=1;} //js判断 var url = '/data/light.php'; // 取Form中要提交的链接 var param = {}; // 组装发送参数 param['light0'] = light0; $.get(url, param, function(dom) { dom=trim(dom); if (dom=='1') { $('#light0_img').attr("src","img/light_on.png"); } else { $('#light0_img').attr("src","img/light_off.png"); } }) ; // 发送并显示返回内容 }); }) 源码在下方下载,其余功能正在开发中..... 实验文档来源:360 | 大小:0MB | 提取密码:f579 | 解压密码:www.rainfly.cn 已经过安全软件检测无毒,请您放心下载。 若链接失效可联系管理员!
2016年-8月-24日
10710 阅读
11 评论
Linux嵌入式
2016-8-17
网络编程socket之bind函数
摘要 :在套接口中,一个套接字只是用户程序与内核交互信息的枢纽,它自身没有太多的信息,也没有网络协议地址和端口号等信息,在进行网络通信的时候,必须把一个套接字与一个地址相关联,这个过程就是地址绑定的过程。许多时候内核会我们自动绑定一个地址,然而有时用户可能需要自己来完成这个绑定的过程,以满足实际应用的需要,最典型的情况是一个服务器进程需要绑定一个众所周知的地址或端口以等待客户来连接。这个事由 bind的函数完成。 从bind函数功能我们很容易推测出这个函数的需要的参数与相应的返回值,如果此时大家已经对socket接口有点熟悉了: #include<sys/socket.h> int bind( int sockfd, struct sockaddr* addr, socklen_t addrlen) 返回:0 ──成功, - 1 ──失败 参数sockfd 指定地址与哪个套接字绑定,这是一个由之前的socket函数调用返回的套接字。调用bind的函数之后,该套接字与一个相应的地址关联,发送到这个地址的数据可以通过这个套接字来读取与使用。 参数addr 指定地址。这是一个地址结构,并且是一个已经经过填写的有效的地址结构。调用bind之后这个地址与参数sockfd指定的套接字关联,从而实现上面所说的效果。 参数addrlen 正如大多数socket接口一样,内核不关心地址结构,当它复制或传递地址给驱动的时候,它依据这个值来确定需要复制多少数据。这已经成为socket接口中最常见的参数之一了。 bind函数并不是总是需要调用的,只有用户进程想与一个具体的地址或端口相关联的时候才需要调用这个函数。如果用户进程没有这个需要,那么程序可以依赖内核的自动的选址机制来完成自动地址选择,而不需要调用bind的函数,同时也避免不必要的复杂度。在一般情况下,对于服务器进程问题需要调用 bind函数,对于客户进程则不需要调用bind函数。 bind函数 int bind(SOCKET s,const struct sockaddr FAR *name,int namelen); 当创建了一个Socket以后,套接字数据结构中有一个默认的IP地址和默认的端口号。一个服务程序必须调用bind函数来给其绑定一个IP地址和一个特定的端口号。客户程序一般不必调用bind函数来为其Socket绑定IP地址和断口号。该函数的第一个参数指定待绑定的Socket描述符;第二个参数指定一个sockaddr结构,该结构是这样定义的: struct sockaddr {u_short sa_family;char sa_data[14];}; 其中sin_family置AF_INET;sin_port指明端口号;sin_addr结构体中只有一个唯一的字段s_addr,表示IP地址,该字段是一个整数,一般用函数inet_addr()把字符串形式的IP地址转换成unsigned long型的整数值后再置给s_addr。有的服务器是多宿主机,至少有两个网卡,那么运行在这样的服务器上的服务程序在为其Socket绑定IP地址时可以把htonl(INADDR_ANY)置给s_addr,这样做的好处是不论哪个网段上的客户程序都能与该服务程序通信;如果只给运行在多宿主机上的服务程序的Socket绑定一个固定的IP地址,那么就只有与该IP地址处于同一个网段上的客户程序才能与该服务程序通信。我们用0来填充 sin_zero数组,目的是让sockaddr_in结构的大小与sockaddr结构的大小一致。下面是一个bind函数调用的例子: struct sockaddr_in saddr; saddr.sin_family = AF_INET; saddr.sin_port = htons(8888); saddr.sin_addr.s_addr = htonl(INADDR_ANY); bind(ListenSocket,(struct sockaddr *)&saddr,sizeof(saddr));
2016年-8月-17日
5628 阅读
3 评论
Linux嵌入式
2016-8-15
HTTP协议原理结构分析
1.协议特点 a.C/S模式 b.客户端向服务器发出Request 只需传送请求方法和路径, 通信速度快 方法: GET 通过请求URI得到资源 浏览器向服务器一般请求 POST,用于添加新的内容 发送form表单 PUT 用于修改某个内容 DELETE, 删除某个内容 CONNECT, 用于代理进行传输,如使用SSL OPTIONS 询问可以执行哪些方法 PATCH, 部分文档更改 PROPFIND 查看属性 PROPPATCH 设置属性 MKCOL 创建集合(文件夹) COPY 拷贝 MOVE 移动 LOCK 加锁 UNLOCK 解锁 TRACE 用于远程诊断服务器 HEAD 类似于GET, 但是不返回body信息,用于检查对象是否存在,以及得到对象的元数据 c. 传输类型很灵活:只需要给它加上Content-Type MIME类型值即可 d.发送完请求报文,立即和服务器断开连接(PS:虽然TCP的80端口可以建立多个Socket连接但是如果连接过多服务器响应其他请求放慢),服务器所需要完成的是将端口接受请求放入等待队列,根据算法进行选择相应的连接请求进行处理。 节省了客户端进行等待的时间 e.发送完数据包之后,如果服务器不Response,需要将所有的数据包重新发送。 2.文件格式 Request: 请求报文格式 请求报文可以用Google浏览器进行查看其发送 发送的报文实例 POST报文头如下: POST /sn/index.php HTTP/1.1 Accept: */* Accept-Language: zh-cn host: localhost Content-Type: application/x-www-form-urlencoded Content-Length: 12 Connection:close sn=123&n=asa 在http头后边有一空行,空行后边接着发送post数据,长度通过Content-Length: 12 指出,此post数据中包含两项 sn=123 n=asa 其中:Content-Type: application/x-www-form-urlencoded 指定POST数据的编码类型 Content-Length: 12 POST数据的长度 GET: GET报问头如下: GET /sn/index.php?sn=123&n=asa HTTP/1.1 Accept: */* Accept-Language: zh-cn host: localhost Content-Type: application/x-www-form-urlencoded Content-Length: 12 Connection:close Response :响应报文格式 相应阶段报文,给一个API 调试工具 使用GET请求获得数据 http://apistore.baidu.com/astore/toolshttpproxy 我给http:www.baidu.com服务器发送了一个GET请求下面是相应回复的报文 Response Header HTTP/1.1 200 OK Date: Tue, 16 Aug 2016 01:58:22 GMT Content-Type: text/html; charset=utf-8 Transfer-Encoding: chunked Connection: Keep-Alive Vary: Accept-Encoding Set-Cookie: BAIDUID=E6BADB45ADCAFAF36BAE6C63E46613C9:FG=1; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com Set-Cookie: BIDUPSID=E6BADB45ADCAFAF36BAE6C63E46613C9; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com Set-Cookie: PSTM=1471312702; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com Set-Cookie: BDSVRTM=0; path=/ Set-Cookie: BD_HOME=0; path=/ Set-Cookie: H_PS_PSSID=1465_18241_17949_18560_17001_11693_20848_20856_20837_20771_20719; path=/; domain=.baidu.com P3P: CP=" OTI DSP COR IVA OUR IND COM " Cache-Control: private Cxy_all: baidu+955142e509dca9cdda759e1be73fb859 Expires: Tue, 16 Aug 2016 01:57:59 GMT X-Powered-By: HPHP Server: BWS/1.1 X-UA-Compatible: IE=Edge,chrome=1 BDPAGETYPE: 1 BDQID: 0xc83e2bbf001302cc BDUSERID: 0 Content-Encoding: gzip 这里可以看到对应上面图二的结果 版本信息:HTTP/1.1 HTTP 1.1中的五类状态码: 100-199 用于指定客户端应相应的某些动作。 200-299 用于表示请求成功。 300-399 用于已经移动的文件并且常被包含在定位头信息中指定新的地址信息。 400-499 用于指出客户端的错误。 500-599 用于支持服务器错误。 OK:就是OK 剩余的都是头部行,携带了一些关于发送时间 格式 编码之类的信息 Content-Encoding: gzip 此处是指服务器将Response文件进行GZIP压缩, 当客户端接收后根据Content-Encoding: gzip执行解压缩 (这种方法会降低服务器宽带压力,但是增加了服务器压力,加快网页打开速度) 对文件部分解码的到了Response Body, 就是HTML信息。 在HTTP协议是建立在TCP/IP传输控制协议基础上的,所以所有的文件必须是客户端和服务器TCP三次握手已经建立连接,后面我还会继续了解剖学习 , 还会用C语言实现 HTTP FTP等应用层协议!
2016年-8月-15日
6522 阅读
1 评论
Linux嵌入式
1
2
3