Linux和网络

概述

提起网络,大家恐怕最熟悉就是下面这条命令了。这个服务器有两个网卡,一个是eth0,一个是本地测试回环。(多说一句,我们在日常副业修电脑中能ping通127.0.0.1不能说明系统网卡安装没有问题,只能证明系统安装的网络协议栈正常)

$ ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.237.65.51  netmask 255.255.255.0  broadcast 10.237.65.255
        inet6 fe80::22a:4aff:fe16:195  prefixlen 64  scopeid 0x20<link>
        ether 00:2a:4a:16:01:95  txqueuelen 1000  (Ethernet)
        RX packets 9086390789  bytes 2530099253863 (2.3 TiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 7359376682  bytes 2408846947163 (2.1 TiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1  (Local Loopback)
        RX packets 73614812  bytes 103574570748 (96.4 GiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 73614812  bytes 103574570748 (96.4 GiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
  1. en代表以太网卡
  2. UP代表当前该网络接口(PCI借口)的状态是开启的
  3. RUNNING代表网卡网卡设备已经链接
  4. MULTICAST 表示支持组播
  5. mtu的数字表示最大支持的传输单元
  6. inet表示ip地址,netmask表示子网掩码,broadcast表是组播地址
  7. ether后面的就是网卡的MAC地址

当然,也会有下面这种典型的网桥设置

bridge0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
	options=63<RXCSUM,TXCSUM,TSO4,TSO6>
	ether 82:7c:1e:68:88:01
	Configuration:
		id 0:0:0:0:0:0 priority 0 hellotime 0 fwddelay 0
		maxage 0 holdcnt 0 proto stp maxaddr 100 timeout 1200
		root id 0:0:0:0:0:0 priority 0 ifcost 0 port 0
		ipfilter disabled flags 0x0
	member: en1 flags=3<LEARNING,DISCOVER>
	        ifmaxaddr 0 port 11 priority 0 path cost 0
	member: en2 flags=3<LEARNING,DISCOVER>
	        ifmaxaddr 0 port 12 priority 0 path cost 0
	member: en3 flags=3<LEARNING,DISCOVER>
	        ifmaxaddr 0 port 13 priority 0 path cost 0
	member: en4 flags=3<LEARNING,DISCOVER>
	        ifmaxaddr 0 port 14 priority 0 path cost 0
	nd6 options=201<PERFORMNUD,DAD>
	media: <unknown type>
	status: inactive

还有 llw0 (WLAN low-latency interface),awdl0(Apple Wireless Direct Link),p2p0(air drop用的就是这个),utun(用户空间隧道)这几个是mac电脑自己的。不需要关注。
我们几乎只需要关注en和brige就可以了。比如我这台mac的无线网卡的mac地址是
在这里插入图片描述
对应en0。

en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
	options=400<CHANNEL_IO>
	ether 14:7d:da:e0:23:43
	inet6 fe80::16:9517:b887:4a51%en0 prefixlen 64 secured scopeid 0xa
	inet 172.18.233.100 netmask 0xffff8000 broadcast 172.18.255.255
	nd6 options=201<PERFORMNUD,DAD>
	media: autoselect
	status: active

而所谓的霹雳网桥对应en1。使用的是不同的物理网卡。
同样,Linux服务器可以安装多个物理网卡。

一个网卡可以配置多个IP地址。LINUX最多可以支持255个IP子网卡(也被称为网卡子接口)。
配置网卡子接口前

ifconfig -a
eno16777736: flags=4098 mtu 1500

配置

sudo ip addr add 192.168.1.249/24 dev eno16777736 label eno16777736:0

配置子网卡后

ifconfig
eno16777736:
 inet 192.168.1.113  netmask 255.255.255.0  broadcast 255.255.255.255
eno16777736:0:
 inet 192.168.1.249  netmask 255.255.255.0  broadcast 0.0.0.0

有讨厌的小伙伴们要问这个问题,那可不可以同时访问内网和外网呢?(这是严重损害公司网络安全的行为,千万千万谨慎)

## 访问以 172.22 开头的ip都走 172.22.1.129 这个内网网关,否则全部走 192.168.43.1 这个外网网关。-p表示添加永久路由
route add -p 0.0.0.0 mask 0.0.0.0 192.168.43.1
route add -p 172.22.0.0 mask 255.255.0.0 172.22.1.129

网络代理

有些事情的原理。其实并没有复杂,就是拆包,改IP头而已。

内网穿透

有些人喜欢自己外出能手机看到家里的监控。但是ISP很难给你分配一个永久公网IP,很可能只是给了你一个临时公网IP,甚至只给了你一个内网IP。要么去要一个公网IP,要么没有办法就是把自己的家里的监控传给小米,小米再转发给你的手机。小米会偷看吗?

再比如,你希望和朋友联机打游戏,但是游戏只支持局域网联机。怎么办?

TCP6

IPV4协议栈也可以运行在TCP6上,IPV4的地址可以映射到IPV6的地址上。

$ netstat -apn|grep 6805
(No info could be read for "-p": geteuid()=1001 but you should be root.)
tcp6       1      0 10.237.65.55:6805       10.5.147.40:8180        CLOSE_WAIT  -
tcp6       0      0 10.237.65.55:26600      10.237.65.58:6805       ESTABLISHED -

在一些版本中,如centos7中,TCP和TCP6是共存的。

端口号

1024以下是操作系统默认保留的。1024~65000可以给用户使用。可以通过

cat /proc/sys/net/ipv4/ip_local_port_range

来查看。我这台服务器上的是

2930~65500

UDP和TCP共同使用端口号空间
对于主动的对外连接,采用动态分配法。服务端有必要确定监听的端口号,但是接受服务的客户端不需要确定端口号。

客户端应用程序不用设置端口号,由操作系统进行分配。操作系统可以为每个应用程序分配不冲突的端口号。比如:每需要一个新的端口号时,就在之前分配号码的基础上加 1 。这样,操作系统就可以动态管理端口号了。

动态分配的端口号范围是 49152 ~ 65535 之间。

Socket

socket是一种变成模型。是对传输层的抽象。用户代码通过操作socket来操作网络。
linux主张一切都是文件,所以socket本质上也是一个文件。
注意,一个socket在调用accept的时候,会生成一个socket。这个socket和原来监听的socket共用端口。但是不是一个【socket】!!!

确定唯一socket的是四元组
{源IP,源端口,目标IP,目标端口}
两者缺一不可。
所以,我们知道,一个客户端最多可以发起端口号为上限的socket。而一个服务器端接受的socket则以自身打开文件的上限决定。

在这里插入图片描述

创建一个socket

#include <sys/types.h>
#include <sys/socket.h>
int socket(int domain,int type, int protocol);

domain指的是IPV4还是IPV6,tpye表示是UDP还是TCP。protocol应该是默认值0。

#include <sys/types.h>
#include <sys/socket.h>
int bind(int sockfd,const sockaddr* my_addr,socklen_t addrlen);

将某一个TCP连接绑定到某一个文件描述符

下面两个API对应被动接受连接的一方(服务器端)

#include <sys/socket.h>
int listen(int sockfd, int backlog);

监听指定的socket的文件描述符。

#include <sys/types.h>
#include <sys/socket.h>
int accept(int sockfd,struct sockaddr *addr, socklen *addrlen);

从指定的文件描述符接受一个连接。这个文件描述符必须调用过上面的listen才行。

下面的API对应主动发起连接的一方(客户端)

#include <sys/types.h>
#include <sys/socket.h>
int connect(int sockfd,const struct sockaddr *serv_addr,socklen_t addrlen);

端口释放问题

一个实际编程中经常遇到的问题是,进程死了,其申请的端口是否还在呢?

lsof -i:端口号
netstat -tunlp|grep 端口号

最容易出问题的情况是父进程死掉了,子进程还在。资源不释放完全在情理之中。
另一种情况下是linux的TimeWait的问题。Linux的TimeWait默认时间是2分钟。

大量TimeWait的解决方案

  • 一种可行的方案是修改内核参数
net.ipv4.tcp_tw_reuse = 1表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭;
net.ipv4.tcp_tw_recycle = 1表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。
net.ipv4.tcp_fin_timeout修改系統默认的TIMEOUT时间

操作系统的内核参数的优化

所有的TCP/IP参数都位于/proc/sys/net目录下(请注意,对/proc/sys/net目录下内容的修改都是临时的,任何修改在系统重启后都会丢失)。

详细请查询
https://www.cnblogs.com/zengkefu/p/5749009.html

下面列举一些常见的坑

net.ipv4.tcp_tw_reuse = 1
#表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭;

高版本Linux不再支持tcp_tw_recycle。听着很美好,但是默认关闭就好。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值