# 其他

## 1 环境变量

> .bashrc

```
# x1-cli
export BUTTERFLY_HANDLER_CLI_NAME="x1-cli"
export BUTTERFLY_HOME=/home/work/x1-cli
[[ -s "${BUTTERFLY_HOME}/bin/x1-bash-complete.sh" ]] && source ${BUTTERFLY_HOME}/bin/x1-bash-complete.sh
export PATH=${BUTTERFLY_HOME}/bin:$PATH
```

* 在 shell 脚本中，`-s` 用于文件测试来判断文件是否存在且非空。

## 2 tcpdump

**监视指定主机和端口的数据包**

```
tcpdump tcp port 6379 and host 10.xx.xx.xx

-w 选项用来把数据报文输出到文件
文件需要使用 tcpdump -r 来读取
```

**监控 HTTP 流量，包括请求和响应标头以及消息正文(需要将端口 8585 改为实际使用的端口)**

```
tcpdump -A -s 0 'tcp port 8585 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)' 
```

* `-A`: 这个选项意味着以 ASCII 格式显示数据包的内容，使得文本数据更容易阅读。
* `-s 0`: 这个选项设置了捕获每个数据包的长度。`0` 表示捕获整个数据包，不进行截断。

**tcpdump 的输出**

```
21:27:06.995846 IP 192.168.1.106.56166 > 124.192.132.54.80: Flags [S], seq 992042666, win 65535, options [mss 1460,nop,wscale 4,nop,nop,TS val 663433143 ecr 0,sackOK,eol], length 0
21:27:07.030487 IP 124.192.132.54.80 > 192.168.1.106.56166: Flags [S.], seq 2147006684, ack 992042667, win 14600, options [mss 1440], length 0
21:27:07.030527 IP 192.168.1.106.56166 > 124.192.132.54.80: Flags [.], ack 2147006685, win 65535, length 0
```

最基本也是最重要的信息就是数据报的源地址/端口和目的地址/端口，上面的例子第一条数据报中，源地址 ip 是 `192.168.1.106`，源端口是 `56166`，目的地址是 `124.192.132.54`，目的端口是 `80`。 `>` 符号代表数据的方向。

此外，上面的三条数据还是 tcp 协议的三次握手过程，第一条就是 `SYN` 报文，这个可以通过 `Flags [S]` 看出。下面是常见的 TCP 报文的 Flags:

* `[S]` : SYN（开始连接）
* `[.]` : 没有 Flag
* `[P]` : PSH（推送数据）
* `[F]` : FIN （结束连接）
* `[R]` : RST（重置连接）

而第二条数据的 `[S.]` 表示 `SYN-ACK`，就是 `SYN` 报文的应答报文。

## 3 对比两个文件夹是否一致

diff -urNa dir1 dir2

## 4 排查 vip 残余流量

> 将 vip 后端地址指向到 tcp 测试地址

```
import socket

def start_tcp_server(host='0.0.0.0', port=8003):
    # 创建一个TCP/IP套接字
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 绑定套接字到地址
    server_socket.bind((host, port))
    # 监听传入连接
    server_socket.listen(1)
    print "Server listening on %s:%d" % (host, port)

    try:
        while True:
            # 等待一个连接
            client_socket, client_address = server_socket.accept()
            print "Connected by", client_address

            # 在这里可以添加处理客户端连接的代码
            # 例如，接收数据
            # data = client_socket.recv(1024)
            # 如果需要，可以打印接收到的数据
            # print "Received", data

            # 注意：在实际应用中，你应该有一个机制来关闭client_socket，
            # 例如，在接收到特定命令或发生错误时。
            # 在这个简单示例中，我们没有实现关闭连接的逻辑。

            # 为了演示目的，我们在这里不关闭client_socket，
            # 但这在实际应用中是不推荐的，因为它会导致资源泄露。
            # 在实际应用中，你应该在适当的时候关闭client_socket。

            # 注意：由于Python 2的默认行为，未显式关闭的文件或套接字
            # 可能会在程序结束时由垃圾回收器关闭，但这不应该被视为一种可靠的关闭机制。

            # 在这个示例中，为了保持简单性，我们没有实现数据发送或接收的逻辑，
            # 也没有实现错误处理或资源清理的代码。
            # 在实际应用中，你应该添加这些必要的逻辑来确保程序的健壮性和可靠性。

    finally:
        # 确保套接字在程序结束时被关闭
        server_socket.close()

if __name__ == "__main__":
    start_tcp_server()
```

将会打印如下信息

```
Connected by ('127.0.0.1', 15712)
Connected by ('xx.xx.xx.xx', 23783)
```
