网络-TCP

TCP协议对比UDP具有更高的稳定性,能确保数据的可靠传输。在聊天软件中,通常聊天用UDP,文件传输用TCP。以迅雷为例,TCP下载过程中会不断回传已下载部分的确认信息,实现分块下载。TCP流程包括客户端、服务器交互,以及多客户端服务等环节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

以下为初学者理解:

  • TCP必须区分客户端和服务器,TCP的稳定性比UDP高。

  • 比如a向b发送消息,用UDP发送后,你不知道b到底有没有收到消息,而使用TCP发送,b收到消息后服务器会给a一个反馈u信息,a就知道b收到了消息。

  • 很多聊天软件,聊天使用的是UDP而发送文件则使用的是TCP。

  • 迅雷用的就是TCP,下载东西时你留意下就会发现,会有上传数据,这是怎么回事那?
    比如:你要下载一个5G的电影,它会分成很多块发给你进行下载,下载一部分,会给系统一个回传值告诉系统这部分下载好了,然后再发下一部分进行下载,依次类推直到下载完毕。

  • TCP流程图:
    在这里插入图片描述


# 设置当服务器先close 即服务器端4次挥手之后资源能够立即释放,这样就保证了,下次运行程序时 可以立即绑定7788端口
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

yy_01_tcp客户端

import socket


def main():

	# 1.创建tcp套接字
	tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

	# 2.链接服务器
	server_ip = input("请输入要链接的服务器ip:")
	server_port = int(input("请输入要链接的服务器port:"))
	server_addr = (server_ip, server_port)
	tcp_socket.connect(server_addr)

	# 3.发送/接收数据
	send_data = input("请输入要发送的数据:")
	tcp_socket.send(send_data.encode("utf-8"))

	# 4.关闭套接字
	tcp_socket.close()


if __name__ == "__main__":
    main()


yy_02_tcp服务器

import socket


def main():

	# 1.买个手机(创建tcp套接字)
	tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

	# 2.插入手机卡(绑定本地信息 bind)
	tcp_server_socket.bind(("", 7785))
	

	# 3.将手机设置为正常响铃模式(让默认的套接字由主动变为被动 listen)
	tcp_server_socket.listen(128)

	print("----1----")
	# 4.等待别人的电话到来(等待客户端的链接 accept)
	new_client_socket, client_addr = tcp_server_socket.accept()
	print("----2----")

	print(client_addr)

	# 5.接收客户端发过来的请求
	recv_data = new_client_socket.recv(1024)
	print(recv_data.decode("utf-8"))

	# 6.回送一部分数据给客户端
	new_client_socket.send("---ok---".encode("utf-8"))

	# 7.关闭套接字
	new_client_socket.close()
	tcp_server_socket.close()
	


if __name__ == "__main__":
    main()


yy_03_循环为多个客户端服务

import socket


def main():

	# 1.买个手机(创建tcp套接字)
	tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

	# 2.插入手机卡(绑定本地信息 bind)
	tcp_server_socket.bind(("", 7785))
	

	# 3.将手机设置为正常响铃模式(让默认的套接字由主动变为被动 listen)
	tcp_server_socket.listen(128)

	while True:
		
		print("等待一个新发客户端到来")
		# 4.等待别人的电话到来(等待客户端的链接 accept)
		new_client_socket, client_addr = tcp_server_socket.accept()
		

		print("一个新的客户端来了 %s" % str(client_addr))

		
		# 5.接收客户端发过来的请求
		recv_data = new_client_socket.recv(1024)


		print("客户端发过来的请求是: %s" % str(recv_data.decode("utf-8")))

		# 6.回送一部分数据给客户端
		new_client_socket.send("---ok---".encode("utf-8"))

		# 7.关闭套接字

		# 关闭accept返回的套接字,意味着 不会在为这个客户端服务
		new_client_socket.close()
		print("服务完毕!")


	# 如果将监听套接字关闭,就会导致 不能再次等待新客户的到来, 即xxxx.accept就会失败
	tcp_server_socket.close()
	


if __name__ == "__main__":
    main()


yy_04_循环为多个客户端服务,并且多次服务一个客户端

import socket


def main():

	# 1.买个手机(创建tcp套接字)
	tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

	# 2.插入手机卡(绑定本地信息 bind)
	tcp_server_socket.bind(("", 7785))
	

	# 3.将手机设置为正常响铃模式(让默认的套接字由主动变为被动 listen)
	tcp_server_socket.listen(128)

	while True:
		
		print("等待一个新发客户端到来")
		# 4.等待别人的电话到来(等待客户端的链接 accept)
		new_client_socket, client_addr = tcp_server_socket.accept()
		

		print("一个新的客户端来了 %s" % str(client_addr))

		while True:
			
			# 5.接收客户端发过来的请求
			recv_data = new_client_socket.recv(1024)

			print("客户端发过来的请求是: %s" % str(recv_data.decode("utf-8")))

			if recv_data:
				# 6.回送一部分数据给客户端
				new_client_socket.send("---ok---".encode("utf-8"))
			
			else:
				break
		
		# 7.关闭套接字

		# 关闭accept返回的套接字,意味着 不会在为这个客户端服务
		new_client_socket.close()
		print("服务完毕!")


	# 如果将监听套接字关闭,就会导致 不能再次等待新客户的到来, 即xxxx.accept就会失败
	tcp_server_socket.close()
	


if __name__ == "__main__":
    main()


yy_05_案例-下载文件(客户端)

import socket


def main():
	# 1.创建套接字
	tcp_down_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

	# 2.获取服务器的ip/port
	serve_ip = input("请输入下载服务器的ip:")
	serve_port = int(input("请输入下载服务器的port:"))

	# 3.链接服务器
	tcp_down_socket.connect((serve_ip, serve_port))

	# 4.获取下载的文件姓名
	down_name = input("请输入要下载的文件:")

	# 5.将文件名字发到服务器
	tcp_down_socket.send(down_name.encode("utf-8"))

	# 6.接收文件中的数据 - 是二进制
	recv_date = tcp_down_socket.recv(1024*1024)  # 1024kb=1k 1024*1024=1k*1024=1M

	# 7.保存接收到的数据到一个文件中 - b(bytes)二进制写入 
	with open("[新]" + down_name, "wb") as f:
		f.write(recv_date)

	# 8.关闭套接字
	tcp_down_socket.close()


if __name__ == '__main__':
	main()

yy_06_案例-下载文件(服务器)

import socket


def send_file_2_client(new_client_socket, client_addr):  # 2相当与to 
	
	# 5.接收客户端发过来的请求
	file_name = new_client_socket.recv(1024*1024).decode("utf-8")
	print("客户端[%s]需要下载的文件是:%s" % (str(client_addr), file_name))

	file_content = None
	# 打开文件,读取数据
	try:
		f = open(file_name, "rb")
		file_content = f.read()
		f.close()
	except Exception as e:
		print("没有要下载的文件%s" % file_name)

	# 6.发送文件的数据给客户端
	if file_content:
		new_client_socket.send(file_content)


def main():
	# 1.创建套接字
	tcp_screct_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
	
	# 2.绑定本地信息
	tcp_screct_socket.bind(("", 7788))
	
	# 3.让默认的套接字由主动变为被动 listen
	tcp_screct_socket.listen(128)
	while True:
				
		# 4.等待客户端的链接 accept
		new_client_socket, client_addr = tcp_screct_socket.accept()

		send_file_2_client(new_client_socket, client_addr)

		# 7.关闭套接字
		new_client_socket.close()
	
	tcp_screct_socket.close()
	
	

if __name__ == '__main__':
	main()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值