
网络字节顺序NBO(Network Byte Order):
按从高到低的顺序存储,在网络上使用统一的网络字节顺序,可以避免兼容性问题。
主机字节顺序(HBO,Host Byte Order):
不同的机器HBO不相同,与CPU设计有关
计算机数据存储有两种字节优先顺序:高位字节优先和低位字节优先。Internet上数据以高位字节优先顺序在网络上传输,所以对于在内部是以低位字节优先方式存储数据的机器,在Internet上传输数据时就需要进行转换。
我们要讨论的第一个结构类型是:struct sockaddr,该类型是用来保存socket信息的:
struct sockaddr {
unsigned short sa_family; / 地址族, AF_xxx /
char sa_data[14]; / 14 字节的协议地址 / };
sa_family一般为AF_INET;sa_data则包含该socket的IP地址和端口号。
另外还有一种结构类型:
struct sockaddr_in {
short int sin_family; / 地址族 /
unsigned short int sin_port; / 端口号 /
struct in_addr sin_addr; / IP地址 /
unsigned char sin_zero[8]; / 填充0 以保持与struct sockaddr同样大小 /
};
这个结构使用更为方便。sin_zero(它用来将sockaddr_in结构填充到与struct sockaddr同样的长度)应该用bzero()或memset()函数将其置为零。指向sockaddr_in 的指针和指向sockaddr的指针可以相互转换,这意味着如果一个函数所需参数类型是sockaddr时,你可以在函数调用的时候将一个指向 sockaddr_in的指针转换为指向sockaddr的指针;或者相反。sin_family通常被赋AF_INET;sin_port和 sin_addr应该转换成为网络字节优先顺序;而sin_addr则不需要转换。
我们下面讨论几个字节顺序转换函数:
htons()--"Host to Network Short" ; htonl()--"Host to Network Long"
ntohs()--"Network to Host Short" ; ntohl()--"Network to Host Long"
在这里, h表示"host" ,n表示"network",s 表示"short",l表示 "long"。
打开socket 描述符、建立绑定并建立连接
socket函数原型为:
int socket(int domain, int type, int protocol);
domain参数指定socket的类型:SOCK_STREAM 或SOCK_DGRAM;protocol通常赋值“0”。Socket()调用返回一个整型socket描述符,你可以在后面的调用使用它。
一旦通过socket调用返回一个socket描述符,你应该将该socket与你本机上的一个端口相关联(往往当你在设计服务器端程序时需要调用该函数。随后你就可以在该端口监听服务请求;而客户端一般无须调用该函数)。 Bind函数原型为:
int bind(int sockfd,struct sockaddr my_addr, int addrlen);
Sockfd是一个socket描述符,my_addr是一个指向包含有本机IP地址及端口号等信息的sockaddr类型的指针;addrlen常被设置为sizeof(struct sockaddr)。
最后,对于bind 函数要说明的一点是,你可以用下面的赋值实现自动获得本机IP地址和随机获取一个没有被占用的端口号:
my_addrsin_port = 0; / 系统随机选择一个未被使用的端口号 /
my_addrsin_addrs_addr = INADDR_ANY; / 填入本机IP地址 /
通过将my_addrsin_port置为0,函数会自动为你选择一个未占用的端口来使用。同样,通过将 my_addrsin_addrs_addr置为INADDR_ANY,系统会自动填入本机IP地址。Bind()函数在成功被调用时返回0;遇到错误时返回“-1”并将errno置为相应的错误号。另外要注意的是,当调用函数时,一般不要将端口号置为小于1024的值,因为1~1024是保留端口号,你可以使用大于1024中任何一个没有被占用的端口号。
Connect()函数用来与远端服务器建立一个TCP连接,其函数原型为:
int connect(int sockfd, struct sockaddr serv_addr, int addrlen);
Sockfd是目的服务器的sockt描述符;serv_addr是包含目的机IP地址和端口号的指针。遇到错误时返回-1,并且errno中包含相应的错误码。进行客户端程序设计无须调用bind(),因为这种情况下只需知道目的机器的IP地址,而客户通过哪个端口与服务器建立连接并不需要关心,内核会自动选择一个未被占用的端口供客户端来使用。
Listen()——监听是否有服务请求
在服务器端程序中,当socket与某一端口捆绑以后,就需要监听该端口,以便对到达的服务请求加以处理。
int listen(int sockfd, int backlog);
Sockfd是Socket系统调用返回的socket 描述符;backlog指定在请求队列中允许的最大请求数,进入的连接请求将在队列中等待accept()它们(参考下文)。Backlog对队列中等待服务的请求的数目进行了限制,大多数系统缺省值为20。当listen遇到错误时返回-1,errno被置为相应的错误码。
故服务器端程序通常按下列顺序进行函数调用:
socket(); bind(); listen(); / accept() goes here /
accept()——连接端口的服务请求。
当某个客户端试图与服务器监听的端口连接时,该连接请求将排队等待服务器accept()它。通过调用accept()函数为其建立一个连接,accept()函数将返回一个新的socket描述符,来供这个新连接来使用。而服务器可以继续在以前的那个 socket上监听,同时可以在新的socket描述符上进行数据send()(发送)和recv()(接收) *** 作:
int accept(int sockfd, void addr, int addrlen);
sockfd是被监听的socket描述符,addr通常是一个指向sockaddr_in变量的指针,该变量用来存放提出连接请求服务的主机的信息(某台主机从某个端口发出该请求);addrten通常为一个指向值为sizeof(struct sockaddr_in)的整型指针变量。错误发生时返回一个-1并且设置相应的errno值。
Send()和recv()——数据传输
这两个函数是用于面向连接的socket上进行数据传输。
Send()函数原型为:
int send(int sockfd, const void msg, int len, int flags);
Sockfd是你想用来传输数据的socket描述符,msg是一个指向要发送数据的指针。
Len是以字节为单位的数据的长度。flags一般情况下置为0(关于该参数的用法可参照man手册)。
char msg = "Beej was here!"; int len, bytes_sent;
len = strlen(msg); bytes_sent = send(sockfd, msg,len,0);
Send()函数返回实际上发送出的字节数,可能会少于你希望发送的数据。所以需要对send()的返回值进行测量。当send()返回值与len不匹配时,应该对这种情况进行处理。
recv()函数原型为:
int recv(int sockfd,void buf,int len,unsigned int flags);
Sockfd是接受数据的socket描述符;buf 是存放接收数据的缓冲区;len是缓冲的长度。Flags也被置为0。Recv()返回实际上接收的字节数,或当出现错误时,返回-1并置相应的errno值。
Sendto()和recvfrom()——利用数据报方式进行数据传输
在无连接的数据报socket方式下,由于本地socket并没有与远端机器建立连接,所以在发送数据时应指明目的地址,sendto()函数原型为:
int sendto(int sockfd, const void msg,int len,unsigned int flags,const struct sockaddr to, int tolen);
该函数比send()函数多了两个参数,to表示目地机的IP地址和端口号信息,而tolen常常被赋值为sizeof (struct sockaddr)。Sendto 函数也返回实际发送的数据字节长度或在出现发送错误时返回-1。
Recvfrom()函数原型为:
int recvfrom(int sockfd,void buf,int len,unsigned int flags,struct sockaddr from,int fromlen);
from是一个struct sockaddr类型的变量,该变量保存源机的IP地址及端口号。fromlen常置为sizeof (struct sockaddr)。当recvfrom()返回时,fromlen包含实际存入from中的数据字节数。Recvfrom()函数返回接收到的字节数或当出现错误时返回-1,并置相应的errno。
应注意的一点是,当你对于数据报socket调用了connect()函数时,你也可以利用send()和recv()进行数据传输,但该socket仍然是数据报socket,并且利用传输层的UDP服务。但在发送或接收数据报时,内核会自动为之加上目地和源地址信息。
Close()和shutdown()——结束数据传输
当所有的数据 *** 作结束以后,你可以调用close()函数来释放该socket,从而停止在该socket上的任何数据 *** 作:close(sockfd);
你也可以调用shutdown()函数来关闭该socket。该函数允许你只停止在某个方向上的数据传输,而一个方向上的数据传输继续进行。如你可以关闭某socket的写 *** 作而允许继续在该socket上接受数据,直至读入所有数据。
int shutdown(int sockfd,int how);
Sockfd的含义是显而易见的,而参数 how可以设为下列值:
·0-------不允许继续接收数据
·1-------不允许继续发送数据
·2-------不允许继续发送和接收数据,均为允许则调用close ()
shutdown在 *** 作成功时返回0,在出现错误时返回-1(并置相应errno)。
DNS——域名服务相关函数
由于IP地址难以记忆和读写,所以为了读写记忆方便,人们常常用域名来表示主机,这就需要进行域名和IP地址的转换。函数gethostbyname()就是完成这种转换的,函数原型为:
struct hostent gethostbyname(const char name);
函数返回一种名为hosten的结构类型,它的定义如下:
struct hostent {
char h_name; / 主机的官方域名 /
char h_aliases; / 一个以NULL结尾的主机别名数组 /
int h_addrtype; / 返回的地址类型,在Internet环境下为AF-INET /
int h_length; /地址的字节长度 /
char h_addr_list; / 一个以0结尾的数组,包含该主机的所有地址/
};
#define h_addr h_addr_list[0] /在h-addr-list中的第一个地址/
2、将主机的unsigned long值转换为网络字节顺序(32位):为什么要这样做呢?因为不同的计算机使用不同的字节顺序存储数据。因此任何从Winsock函数对IP地址和端口号的引用和传给Winsock函数的IP地址和端口号均时按照网络顺序组织的。
&<60;&<60;&<60;&<60;&<60; u_long&<60; htonl(u_long hostlong);
&<60;&<60;&<60;&<60;&<60; 举例:htonl(0)=0
&<60;&<60;&<60;&<60;&<60; htonl(80)= 1342177280
3、将unsigned long数从网络字节顺序转换位主机字节顺序,是上面函数的逆函数。&<60;&<60;&<60;&<60;&<60;&<60; u_long&<60; ntohl(u_long netlong);
&<60;&<60;&<60;&<60;&<60; 举例:ntohl(0)=0
&<60;&<60;&<60;&<60;&<60; ntohl(1342177280)= 80
1342177280 = 80256256256
4、将主机的unsigned short值转换为网络字节顺序(16位):原因同2:&<60;&<60;&<60;&<60;&<60;&<60; u_short&<60; htons(u_short hostshort);
&<60;&<60;&<60;&<60;&<60; 举例:htonl(0)=0
&<60;&<60;&<60;&<60;&<60; htonl(80)= 20480
5、将unsigned short数从网络字节顺序转换位主机字节顺序,是上面函数的逆函数。&<60;&<60;&<60;&<60;&<60;&<60; u_short&<60; ntohs(u_short netshort);
&<60;&<60;&<60;&<60;&<60; 举例:ntohs(0)=0
&<60;&<60;&<60;&<60;&<60; ntohsl(20480)= 80
20480 = 8-256 (大小端地址转换)
不同的CPU有不同的字节序类型 这些字节序是指整数在内存中保存的顺序 这个叫做主机序
最常见的有两种
1. Little endian:将低序字节存储在起始地址
2. Big endian:将高序字节存储在起始地址
LE little-endian
最符合人的思维的字节序
地址低位存储值的低位
地址高位存储值的高位
怎么讲是最符合人的思维的字节序,是因为从人的第一观感来说
低位值小,就应该放在内存地址小的地方,也即内存地址低位
反之,高位值就应该放在内存地址大的地方,也即内存地址高位
BE big-endian
最直观的字节序
地址低位存储值的高位
地址高位存储值的低位
为什么说直观,不要考虑对应关系
只需要把内存地址从左到右按照由低到高的顺序写出
把值按照通常的高位到低位的顺序写出
两者对照,一个字节一个字节的填充进去最近和阿里的一个老朋友闲聊,感触颇深,据他说公司近期招聘的测试工程师,大多数候选人都有一个“通病”:在工作2-3年的时候遇到瓶颈,而且是一道很难跨越的坎。 为什么会遇到这种情况?因为大部分测试工程师在工作了一段时间后,都可以完成最初的基本知识储备和基础技能积累,技术水平差距不大,通常集中在用例设计、测试执行的掌握程度上。
但如果一个测试工程师只局限于功能测试,只停留在手工点点点,一直沉浸于基础测试技能的熟练度,周而复始他当然会遇到技术瓶颈。 很多人会认为这是一道很难过的坎,却不知,迈过去了,便是海阔天空,你会进入到一个更高的阶段,你会在这个区间继续成长为高端测试人才。迈不过去的人,就可能原地打转,迷茫焦虑,走进瓶颈期,遇到中年危机等
技术线路的职业发展
职业发展一阶:
技术技能要求:执行测试用例,记录测试发现的Bug,跟踪Bug生命周期状态,回归Bug,参与项目测试方案与用例设计等的评审。
对象:一般为刚踏入测试行业的新手。
职业发展二阶:
技术技能要求: 以设计模块级测试方案、测试用例、测试代码为工作重点,执行测试用例为辅;组织模块测试设计评审;参与模块级开发设计方案评审,能独立完成规范的测试流程个节点的工作。
对象:一般为有1-3年经验的测试人员。
职业发展三阶:
技术技能要求: 设计某项目总体测试方案,制订测试计划;对项目的某类或某特性进行测试,如自动化测试、内存泄露、性能测试、安全性测试等;对有一定技术深度或难度方面的测试有独当一面的能力,且收到效果;培养测试新人成为合格的测试工程师。
对象:有3-5年项目测试经验者。
职业发展四阶:
技术技能要求: 制定某类产品测试总体策略、测试流程,制定相关测试规范、指南;负责某类产品测试平台建设;指导重点测试方案设计,对测试设计有一定的创新能力,并收到效果;资深测试工程师的导师。
对象:有5-10年的测试经验者。
职业发展五阶:
技术技能要求: 负责某产品先测试策略、测试方法、流程规范的制定;规划、设计和开发测试平台;为了不断降低公司研发成本而进行新测试技术的研究、实践和推广;技术线上测试人才梯队的结构设计。
作为一个过来人,对过程中的困难深有体会。所以我热衷于收集整理资源,记录踩坑到爬坑的过程。希望能把自己所学,实际工作中使用的技术、自学方法、心得及踩过的一些坑,记录下来。
一、测试基础
了解测试的基础技能,掌握主流缺陷管理工具的使用,熟练测试环境的 *** 作与运维
程序员威子 测试基础
测试计划/测试用例 黑盒用例设计等价类/边界值/场景分析/判定表/因果图分析/错误推断
缺陷 缺陷生命周期/缺陷分级/缺陷管理工具禅道/Jira
数据库 Mysql/环境搭建/增删改查/关联查询/存储过程
Linux 系统搭建/基本指令/日志分析/环境搭建
二、Linux必备知识
Linux作为现在最流行的软件环境系统,一定需要掌握,目前的招聘要求都需要有Linux能力。
程序员威子 Linux必备知识
Linux系统简介与准备 Linux作为现在最流行的软件环境系统,一定得会,从CenterOS版本系统进行介绍,安装,目录结构等基础内容学起,也为后续自建测试环境准备。
Linux远程工具Xshell 详细介绍如何入门使用Linux,并进行常规的远程管理,文件传输 *** 作,涉及其中的工具Xshell,Xftp
Linux文件属性与管理 Linux文件,目录基本属性,文件 *** 作,文件管理,目录 *** 作,目录管理。切忌自毁行为 *** 作,如何预防意外 *** 作
Linux用户与组管理 如何在Linux中新增,删除,修改用户与组,并赋予相应权限,不再因为权限问题而卡壳
Linux文件编辑器 Linux文件编辑器vi的使用,命令模式,输入模式, *** 作实例,快捷键,管道命令,使用心得。在一个没有图形化的系统下到底如何编辑的呢?
Linux常用系统设置 网络设置,环境变量,磁盘管理,时间设置,系统资源,防火墙,应有尽有,不用担心毫无头绪。
Linux安装软件 Linux安装命令,以及如何通过tar,gz等网络上下载的安装文件进行安装,如MySQL数据库安装。
Linux Docker容器 Docker容器技术讲解,image镜像管理,仓库,容器创建,启动, *** 作,镜像打包,赶上行业流行技术
三、Shell脚本
掌握Shell脚本:包括Shell基础与运用、Shell逻辑控制、Shell逻辑函数
程序员威子 Shell
Linux Shell基础与应用 shell脚本编程介绍,环境类型,变量,参数,运算符,数组的使用,零距离接触脚本
Linux Shell逻辑控制 shell逻辑应用,test命令,流程控制,数据输入与输出,脚本逻辑不再单调,玩出花样
Linux Shell函数 shell脚本函数写法,文件互相调用,脚本实战应用,懂得开发,测试,运维都可以做什么
Windows脚本批处理 Linux玩够了,再来看看Windows常规命令用法,批处理脚本写法,实战应用,并不是到哪都是Linux,Windows脚本也是常用脚本之一,看到这里可能你就用的Windows
四、互联网程序原理
自动化必经之路:前端开发基础知识以及互联网网络必备知识四、互联网程序原理
————————————————
版权声明:本文为CSDN博主「程序员威子」的原创文章,遵循CC 40 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:>如果是宽带连接能连上 你就试下这个方法看看网络是否有问题 首先得找你的网络供应商要个他们的DNS服务器地址 然后 在点电脑左下角的开始 选择 运行 输入以下 ping 612342545 -t (我这个地址是举例给你看,你只需把他们告诉你的地址替换下就可以了) 输入好以后按回车 然后你看下有无掉包现象 如果没有掉包 而且很流畅 那就是你没指定正确DNS在本地连接造成 或者浏览器问题,网络设置没有设置好,跟本地连接一样需要设置好ip、子网掩码、网关和dns。有dhcp服务器的话自动获取就可以了,没有自动获取到那就得手动添加啦,不过需要知道你那的网络设置,向你附近的人了解一下吧。这样检查一下:
一、拨打运营商的客服电话,看下外网有没有问题。
二、重新拔插一次网线
猫接出来的网线接在无线路由器的WAN口,电脑接在无线路由器的任一LAN口。
三、把猫和无线路由器都关了再打开,过一会看看。
四、还是不行的话,就重新设置无线路由器。
需要拨号的宽带猫接无线路由器吗,你这样做:
无线路由器插上电,先不要接猫,把无线路由器复位(恢复出厂),电脑连接无线路由器任一LAN口 , 浏览器地址栏输入路由器网关地址(路由器背后标签上有的),进入设置页面,按照PPPOE(ADSL虚拟拨号)方式设置即可。
然后再设置一下SSID、加密方式和 密码 。 保存、重启。
设置好以后,把猫LAN口接出来的网线接在无线路由器的WAN口上。字节跳动ssp是指字节跳动的服务器端广告投放系统,它是一种基于服务器端的广告投放技术,可以让广告主在字节跳动的服务器端实时发布广告,从而更加有效地投放广告。字节跳动ssp的优势在于可以实时发布广告,从而更加有效地投放广告,并且可以根据用户的行为和偏好进行定向投放,从而提高广告的投放效果。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)