python socket编程

Table Of Contents

TCP的三次握手和四次挥手

三次握手:

为什么需要三次握手? 客户端:我可以发东西给你(确保客户端的发送能力) 服务器:我可以收到,你能收到么?(确保服务器的接受和发送) 客户端:我能收到!(确保能收到)

连接建立!

如果是四次握手? 没必要啊,第三次已经确认可以收到消息了

如果是两次握手? 当网络阻塞时,客户端会发送两次,第一次请求到达服务器的时间慢于第二次 如果当时通信结束,服务器又收到了第一次阻塞的消息,如果是两次握手,就会分配资源 然而客户端已经完成了通信,不需要再连接了,会造成资源的浪费和安全隐患

四次挥手:

客户端:我说完了,我想停止发送请求了 服务器:我知道你要停止发送了,我会停止接受消息 ( 服务器停止接受消息,但是可能还有很多待发送的消息

客户端:收到服务器的确认信息,于是默不作声,等待服务器发送完他的消息

) 服务器:我的东西全发完啦!,我想要停止发送消息啦! 客户端:我知道你也要停止发送了,我也要停止接收消息(实际上还等了两个最大周期才真正停止接收消息) ( 服务器:收到了客户端的确认消息,于是停止发送消息 )

关于tcp的博客

使用tcp和udp让进程之间进行通信

ip地址:用來標記網絡上的主機 動態端口:1024-65535的端口,用完就回收

tcp socket client的基本流程

import socket
##創建socket
s = socket.socket(socket.af_inet,socket.sock_stream)
##使用
ipaddr = ("ip",port)#服务器的ip addr
s.connect(ipaddr)#连接服务器
### 发送数据
send_msg = "sasa"
s.send(send_msg.encode("utf-8"))
### 接受数据
recvData = s.rec(1024)#一次接收的字符数
print("recved msg:",recvData.decode(""utf-8))

##關閉
s.close()

tcp server的基本过程

# socket创建套接字
tcp = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# 绑定端口
tcp.bind(("127.1",7788))
# 设置为被动监听
tcp.listen(128)

while True:
	#等待客户端的连接


	#tcp套接字,现在用来被动接听

	# accept阻塞等待链接
	new_client_socket,client_addr = tcp.accept()#阻塞等待一个客户端进行conect,返回元组: 新的套接字,(客户端的ip,端口)
	#有客户端connect后,阻塞解除,返回connect的一个客户端的addr,以及已经和客户端完成连接的套接字,接下来的收发都是用这个新的socket
	
	while True:

		# 处理请求,先收,再发,因此,这里会阻塞等待这个new_client_socket接收到消息
		recv_data = new_client_socket.recv(1024)
		print(recv_data)

		#当recv解阻塞时,有两种情况,1.客户端发送了消息 ;2.客户端调用了close()
		#通过判断recv_data是否为空,那么判断出客户端断开了链接
		if recv_data:
			#收到消息后,我们返回一下,非必要的
			new_client_socket.send("服务器返回的消息".encode('utf-8'))
		else:
			break

	new_client_socket.close()

tcp.close()

創建一個udp socket

import socket

##創建
send_data = input("input:")
s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
#bind a port,接受方可以不绑定
s.bind("",7890)
##使用
#s.sendto(b"test",("127.1",8888))#需要使用二进制第二个参数是元组
s.sendto(send_data.encode("utf-8"),("127.1",8888))#需要编码

s.close()#关闭

socket.socket(AddressFamily,Type) AddressFamily:協議族 Type:套接字類型

绑定端口接收数据

import socket
def main():
	#创建套接字
	udp = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
	#绑定端口
	localaddr = ("",7788)
	udp.bind(localaddr)
	#接收数据
	recv_data = udp.recvfrom(1024)#可以接收的最大字节数
	#打印接受的数据
	#会接收到一个元组二进制流,发送方地址
	msg =  recv_data[0]
	sendaddr = recv_data[1]
	print("%s:%s"%str(sendaddr),msg.decode("utf-8"))#需要解码
	#关闭套接字
	udp.close()
if __name__ == "__main__":
	main()

一个套接字可以同时接收全双工的

一个攻击 扫描端口向缓冲区发送数据

使用tcp进行文件下载

client:

import socket

def main():
	#1.创建套接字
	tcp_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
	#2.获取服务器的ip port
	dest_ip = input("ip:")
	dest_port = input("port:")
	#3.连接服务器
	tcp_socket.connect((dest_ip,dest_port))
	#4.获取下载的名字
	download_file_name = input("input the file name")
	#5.将名字发送到服务器
	tcp_socket.send(download_file_name.encode("utf-8"))
	#6.接受文件中的数据
	recv_data = tcp_socket.recv(1024)#1k
	if recv_data:
		#7.保存文件中的数据
		with open("[new]"+download_file_name,"wb") as f:
			f.write(recv_data)
	#8.关闭套接字
	tcp_socket.close()

if __name__ == "__main__":
	main()

server:

import socket

def send_file2client(new_client_socket,client_addr):
	#1.接受客户端需要下载的文件名
	file_name = new_client_socket.recv(1024).decode('utf-8')
	print("客户端下载的文件是:%s"%(str(client_addr),file_name))
	#2.打开这个文件,读取数据
	file_content = None
	try:
		f = open(file_name,"rb")
		file_content = f.read()
		f.close()
	except Exception as ret:
		print("没有要下载的文件(%s)"%file_name)
	#3.发送文件的数据给客户端
	if file_content:
		new_client_socket.send(file_conect)


def main():
	# socket创建套接字
	tcp_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
	
	# 绑定端口
	tcp_socket .bind(("127.1",7788))
	
	# 设置为被动监听
	tcp_socket .listen(128)

	while True:
		# accept阻塞等待链接
		new_client_socket,client_addr = tcp_socket .accept()#阻塞等待一个客户端进行conect,返回元组: 新的套接字,(客户端的ip,端口)

		# 调用函数,发送文件
		send_file2client(new_client_socket,client_addr)

		# 关闭套接字
		new_client_socket.close()

	tcp_socket .close()


if __name__ == "__main__":
	main()

CC BY-NC 4.0

rust学习
pattern:斑图

Comments