0x01 socket概述
socket
是操作系统抽象出来的一些接口,使用这些接口可以实现基于TCP/IP
来传输数据。
socket
也可以用来网络间进程的通信,同一个机器上的不同进程也可以使用socket
进行通信。
上图的插座就是socket
,插座之间的连线就是传输层以下的被封装的内容,每个插孔都是一个端口,一共65535
个,上层的应用需要使用插孔即端口进行数据交互。
0x02 demo示例
server.py
#!/usr/bin/env pyhton
# coding:utf-8
import socket
import threading
# AF_INET: 基于 IPV4 的网络通信 SOCK_STREAM: 基于 TCP 的流式 socket 通信
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 将套接字绑定到地址
s.bind(('0.0.0.0', 8888))
# 监听TCP传入连接
s.listen(5)
def handle_tcp(sock, addr):
print("new connection from %s:%s" % addr)
sock.send(b'Welcome!')
while True:
data = sock.recv(1024)
if not data:
break
sock.send(b'Hello, %s!' % data)
sock.close()
while True:
sock, addr = s.accept()
# t = threading.Thread(target=handle_tcp, args=(sock, addr))
# t.start()
print addr
sock.send(b'welcome!')
while True:
data = sock.recv(1024)
if not data: break
sock.send(b'hello %s' % data)
sock.close()
client.py
#!/usr/bin/env python
# coding:utf-8
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('**.***.**.**', 8888))
print(s.recv(1024))
for data in [b'dog', b'cat']:
s.send(data)
print(s.recv(1024))
s.close()
测试上例的时候,我将server
端部署到我的阿里云服务器上,client
端部署到我的本地电脑上。因为阿里云有一个公网IP
,如果server
端部署到本地,从阿里云上没法连接到我的本地(当然,可以在出口防火墙上做一个DNAT
)。
附上数据包截图
TCP/IP 握手 & 传输数据 & 分手最上边3
个数据包是三次握手,最后3
个数据包是四次分手(server
端将FIN
包和ACK
包合并在一起发送了,所以看起来像是三次分手)
最后client
需要等待2*MSL
时间,因为它最后发送的ACK
包由于各种网络原因。不一定能发送到server
端,等待2*MSL
期间,如果server
端重新发送来了FIN
包,则表示client
上一个发送的ACK
包丢失了,没有送达到server
,然后再等待2*MSL
,以此类推....
Note:
- 阿里云需要在安全组打开
8888
端口 - 另外,
server
端bind
的ip
地址应该是0.0.0.0
,而不是127.0.0.1
。(0.0.0.0
表示所有ip都可以连接,127.0.0.1
表示只有本机上的进程可以连接)
网友评论