Socket编程 - 网络基础知识
API编程部分:http://www.cnblogs.com/Jimmy1988/p/7895213.html
1. 协议简介
此处,我们主要介绍Linux编程常用的三种协议(TCP/UDP/IP), 关于三种协议的定义,可参见各自的头文件:
- /usr/include/linux/tcp.h
- /usr/include/linux/udp.h
- /usr/include/linux/ip.h
①. TCP
/*
* Come from /usr/include/linux/tcp
*/
struct tcphdr {
__be16 source;
__be16 dest;
__be32 seq;
__be32 ack_seq;
#if defined(__LITTLE_ENDIAN_BITFIELD)
__u16 res1:4,
doff:4,
fin:1,
syn:1,
rst:1,
psh:1,
ack:1,
urg:1,
ece:1,
cwr:1;
#elif defined(__BIG_ENDIAN_BITFIELD)
__u16 doff:4,
res1:4,
cwr:1,
ece:1,
urg:1,
ack:1,
psh:1,
rst:1,
syn:1,
fin:1;
#else
#error "Adjust your <asm/byteorder.h> defines"
#endif
__be16 window;
__sum16 check;
__be16 urg_ptr;
};
Unit | bits | Function |
---|---|---|
源端口 | 16 | 源端口和IP地址的作用是标识报文的返回地址 |
目的端口 | 16 | 端口指明接收方计算机上的应用程序接口 常用端口: - ftp/tftp: 20、21/69 - SSH: 22 - telent: 23 - smtp: 25 - http/https: 80/443 - pop3/snmp: 110/163 (详细信息参见:http://cert.sjtu.edu.cn/doc/linux/ch-ports.html) 或者参见Linux的文件 /usr/services |
序号 | 32 | 本报文段发送的数据组的第一个字节的序号 |
确认序号 | 32 | 下一个期待收到的字节序号 |
数据偏移/首部长度 | 4 | TCP报头的长度 报头长度=首部长度*32bit |
保留 | 4 | 为将来定义新的用途保留,现在一般置0 |
URG | 1 | 紧急指针标志 - 为1时表示紧急指针有效 - 为0则忽略紧急指针 |
ACK | 1 | 确认序号标志 - 为1时表示确认号有效 - 为0表示忽略确认号字段 |
PSH | 1 | push标志 - 1:指示接收方在接收到该报文段以后, 应尽快将这个报文段交给应用程序,而不是在缓冲区排队 |
RST | 1 | 重置连接标志 用于重置由于主机崩溃或其他原因而出现错误的连接。 或者用于拒绝非法的报文段和拒绝连接请求 |
SYN | 1 | 同步序号 用于建立连接过程,在连接请求中, - SYN=1和ACK=0表示该数据段没有使用捎带的确认域; - SYN=1和ACK=1,而连接应答捎带一个确认 |
FIN | 1 | finish标志,用于释放连接 - 1: 表示发送方已经没有数据发送了,即关闭本方数据流 |
窗口 | 16 | 滑动窗口大小 用来告知发送端接受端的缓存大小, 以此控制发送端发送数据的速率, 从而达到流量控制 |
校验和 | 16 | 奇偶校验 此校验和是对整个的 TCP 报文段,包括 TCP 头部和 TCP 数据,以 16 位字进行计算所得; 由发送端计算和存储,并由接收端进行验证。 |
紧急指针 | 16 | 只有当 URG 标志置 1 时紧急指针才有效 紧急指针是一个正的偏移量,和顺序号字段中的值相加 表示紧急数据最后一个字节的序号。 |
选项和填充 | 32 | 表示本端所能接受的最大报文段的长度 |
②. UDP
/*
* Come from /usr/include/linux/udp.h
*/
struct udphdr {
__be16 source;
__be16 dest;
__be16 len;
__sum16 check;
};
Unit | bits | Function |
---|---|---|
源端口 | 16 | 源端口号。在需要对方回信时选用。不需要时可用全0 |
目的端口 | 16 | 目的端口号。这在终点交付报文时必须要使用到 |
长度 | 16 | UDP用户数据报的长度,其最小值是8(仅有首部) |
校验和 | 16 | 检测UDP用户数据报在传输中是否有错。有错就丢弃 |
③. IP
/*
* Comes from /usr/include/linux/ip.h
*/
struct iphdr {
#if defined(__LITTLE_ENDIAN_BITFIELD)
__u8 ihl:4,
version:4;
#elif defined (__BIG_ENDIAN_BITFIELD)
__u8 version:4,
ihl:4;
#else
#error "Please fix <asm/byteorder.h>"
#endif
__u8 tos;
__be16 tot_len;
__be16 id;
__be16 frag_off;
__u8 ttl;
__u8 protocol;
__sum16 check;
__be32 saddr;
__be32 daddr;
/*The options start here. */
};
Unit | bits | Function |
---|---|---|
version | 4 | IP协议的版本 |
IHL (Internet Header Length) |
4 | IP报头的长度 固定部分的长度(20字节)和可变部分的长度之和 Length=IHL*32bit |
TOS (Type Of Service) |
8 | IP数据包的服务类型 |
总长度 | 16 | IP报文的总长度 报头的长度和数据部分的长度之和 |
标识 | 16 | 唯一的标识主机发送的每一分数据报 通常每发送一个报文,它的值加一。 当IP报文长度超过传输网络的MTU(最大传输单元)时必须分片, 这个标识字段的值被复制到所有数据分片的标识字段中, 使得这些分片在达到最终目的地时 可以依照标识字段的内容重新组成原先的数据。 |
标志 | 3 | R、DF、MF三位 目前只有后两位有效 - DF位:为1表示不分片,为0表示分片; - MF:为1表示“更多的片”,为0表示这是最后一片 |
片位移 | 13 | 本分片在原先数据报文中相对首位的偏移位 (需要再乘以8) |
TTL (Time To Live) |
8 | IP报文所允许通过的路由器的最大数量 每经过一个路由器,TTL减1; 当为0时,路由器将该数据报丢弃 |
协议 | 8 | 指出IP报文携带的数据使用的是那种协议, 以便目的主机的IP层能知道要将数据报上交到哪个进程。 - TCP: 6 - UDP: 17 - ICMP: 1 - IGMP: 2 |
首部校验和 | 16 | 计算IP头部的校验和, 检查IP报头的完整性 |
源IP地址 | 32 | 标识IP数据报的源端设备 |
目的IP地址 | 32 | 标识IP数据报的目的地址。 |
2. IPv4相关操作
/* Internet address. */
typedef uint32_t in_addr_t;
struct in_addr
{
in_addr_t s_addr;
};
①. IPv4地址转换
函数 | 参数 | 返回值 | 描述 |
---|---|---|---|
in_addr_t inet_addr( const char *cp) |
cp:十进制字符串 | 成功:0 失败:非0 |
将点分十进制字符串 转换为32位网络字节(大端) |
in_addr_t inet_network( const char *cp) |
cp:十进制字符串 | 成功:32bit 地址 失败:非0 |
将点分十进制字符串 转换为32位主机字节顺序的IP地址 |
char *inet_ntoa( struct in_addr in) |
in:32bit网络IP | 点分十进制字符串 | 将32bit的网络顺序字节 转化为点分十进制字符串方式 |
int inet_aton( const char *cp, struct in_addr *inp |
1.cp: 欲转化的点分十进制IP的首地址 2.inp:转化结果的地址空间首地址 |
成功:0 失败:非0 |
点分十进制字符串 转化为32bit的网络顺序字节顺序 |
②. 获取ID
函数 | 参数 | 返回值 | 描述 |
---|---|---|---|
in_addr_t inet_lnaof( struct in_addr in) |
in:ip地址 | 返回标准主机ID | 获取标准主机ID |
in_addr_t inet_netof( struct in_addr in) |
in:ip地址 | 返回标准主机ID | 获取标准网络ID |
struct in_addr inet_makeaddr( int net, int host) |
1.net:网络ID 2.host:主机ID |
返回IP | 将主机ID和网络ID合成标准IP |
3. 大端小端
- 大端:Big-Endian
即内存高地址存放数据的低字节:如0x1234,存放在0x4000~0x4001,则0x4000存0x12,0x4001存0x34
网络字节顺序统一采用大端- 小端:Little-Endian
与大端相反,即高地址存放高字节
x86系列处理器为小端模式
①.程序判断大小端
#include <stdio.h>
int main()
{
union end_un
{
unsigned short int word;
char ch;
}endian;
endian.word = 0x1234;
if(endian.ch == 0x12)
{
printf("This is Big-Endian!\n");
}
else if(endian.ch == 0x34)
{
printf("This is Little-Endian!\n");
}
return 0;
}
②. 字节顺序转化函数
头文件:#include <arpa/inet.h>
函数数 | 功能 |
---|---|
uint32_t htonl(uint32_t hostlong) | long host to net |
uint16_t htons(uint16_t hostshort) | short host to net |
uint32_t ntohl(uint32_t netlong ) | long net to host |
uint16_t ntohs(uint16_t netshort ) | short net to host |
Socket编程 - 网络基础知识的更多相关文章
- Java Socket编程----网络基础
详见:https://www.cnblogs.com/rocomp/p/4790340.html Java最初是作为网络编程语言出现的,其对网络提供了高度的支持,使得客户端和服务器的沟通变成了现实,而 ...
- python六十七课——网络编程(基础知识了解)
网络编程: 什么是网络编程? 网络:它是一种隐形的媒介:可以将多台计算机使用(将它们连接到一起) 网络编程:将多台计算机之间可以相互通信了(做数据交互) 一旦涉及到网络编程,划分为两个方向存在,一方我 ...
- java第九节 网络编程的基础知识
/** * * 网络编程的基础知识 * 网络协议与TCP/IP * IP地址和Port(端口号) * 本地回路的IP地址:127.0.0.1 * 端口号的范围为0-65535之间,0-1023之间的端 ...
- JAVA基础知识之网络编程——-网络基础(Java的http get和post请求,多线程下载)
本文主要介绍java.net下为网络编程提供的一些基础包,InetAddress代表一个IP协议对象,可以用来获取IP地址,Host name之类的信息.URL和URLConnect可以用来访问web ...
- Java 网络编程(一) 网络基础知识
链接地址:http://www.cnblogs.com/mengdd/archive/2013/03/09/2951826.html 网络基础知识 网络编程的目的:直接或间接地通过网络协议与其他计算机 ...
- Linux运维笔记(一)网络基础知识
网络基础知识 一.基本概念 1.ARPANET & TCP/IP:以“软件”技术将网络硬件整合,使得不同的计算机或者数据可以通过这个软件达成数据沟通(TCP/IP技术也被称为Internet) ...
- Java Socket通讯---网络基础
java socket 通讯 参考慕课网:http://www.imooc.com/learn/161 一.网络基础知识 1.1 通讯示意图 1.2 TCP/IP协议 TCP/IP是世界上应用最为广泛 ...
- iOS网络基础知识
iOS网络基础知识 1.一次HTTP请求的完整过程 (1)浏览器或应用发起Http请求,请求包含Http请求Http(请求),地址(url),协议(Http1.1)请求为头部 (2)web服务器接收到 ...
- 网络基础知识、ASP.NET 核心知识(1)*
为什么要写网络? 我原本的计划是这样的,连续两天梳理ASP.NET开发的核心知识.说到这呢,有人问了.“不是说好了做ASP.NET笔记吗?为啥要写网络基础知识?是不是傻?” 原因是这样的.作为网站开发 ...
随机推荐
- DBCC--CHECKDB--结果收集
--由宋沄剑提供 CREATE TABLE [dbo].[dbcc_history]( [Error] [int] NULL, [Level] [int] NULL, [State] [int] NU ...
- c# async Task await Result 死锁
最近项目数据量较大,使用 async Task异步增加执行效率 遇到问题,当前有2个计算非常耗时,现在需要你优化一下,这2个计算并行执行,2个计算执行完成后将2个结果sum返回给用户 当前我是这样实现 ...
- .NET Entity Framework (with Oracle ODP.NET)
一.前言 1.Entity Framework是什么? Entity Framework是微软对ORM框架的实现.类似的实现也有其它方式,如DevExpress 的XPO(eXpress Persis ...
- Unity的Shader如何控制投影颜色
细节慢慢补充,有几个需要注意的地方,必须要有接收投影的pass也就是Name是ShadowCollector的,必须添加#pragma multi_compile_fwdbase,物体的着色器必须有T ...
- TensorFlow从1到2(十)带注意力机制的神经网络机器翻译
基本概念 机器翻译和语音识别是最早开展的两项人工智能研究.今天也取得了最显著的商业成果. 早先的机器翻译实际脱胎于电子词典,能力更擅长于词或者短语的翻译.那时候的翻译通常会将一句话打断为一系列的片段, ...
- Retrofit源码解析(下)
接着上一章继续分析上一章主要简单说了一下基本使用和注解,这一章,我们主要看源码,废话不多说了,直接上.先上一张图 从网络上拿来的 前面一章说了一下Retrofit的简单使用https://www.cn ...
- 主机安全扫描工具-- vuls
https://vuls.io/ 一. 安装 系统管理员有责任定期去检查系统的弱点和更新软件, vuls 可以提供如下功能: 通知管理员机器有安全隐患 支持本地和远程扫描(需要有 ssh 权限) 可以 ...
- numpy的ravel()和flatten()函数比较
功能 两个函数的功能都是将多维数组降为一维. 用法 import numpy as np arr = np.array([[1, 2],[3, 4]]) arr.flatten() arr.ravel ...
- 【NOIP2013】 华容道 bfs预处理+bfs
这一题我们考虑一个最裸的算法: 我们设$dp[i][j][k][l]$表示当前棋子在$(i,j)$且空格在$(k,l)$时的最小步数 然后显然随便转移一下就好了,时间复杂度为$O(q(nm)^2)$. ...
- LabelRank非重叠社区发现算法介绍及代码实现(A Stabilized Label Propagation Algorithm for Community Detection in Networks)
最近在研究基于标签传播的社区分类,LabelRank算法基于标签传播和马尔科夫随机游走思路上改装的算法,引用率较高,打算将代码实现,便于加深理解. 这个算法和Label Propagation 算法不 ...