udp与tcp

  1. udp
    1. 工作原理描述:类似于写信,知道收件方地址之后,就将信寄出去,不能确定收信人是否收到信。
      因此,udp不安全

    2. udp分为服务器和客户端,客户端访问服务器,有本机随机绑定端口,服务器需要绑定特定端口

客户端:

import socket
# 1. 创建信箱 -- udp套接字
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 2. 接受/发送 数据
# 发送数据,
# 第一个参数需要发送的信息,但必须是byte类型数据,所以字符串要编码encode;
# 第二个参数是元组类型,是ip+port,ip是字符串,端口是数字
udp_socket.sendto(msg.encode('utf-8'), ('192.168.236.129', 8080))
# 接收数据
#客户端从缓存中获取数据,recvfrom的参数就是最大能接收的字节数,可以自己调整
# recvfrom获取的是 (msg, (ip, port))
recv_msg = udp_socket.recvfrom(1024)
# 4. 关闭套接字
udp_socket.close()	

服务器:

import socket
# 1. 创建信箱 -- udp套接字
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 2. 绑定端口,bind的参数是元组,ip+port,ip是字符串,端口是数字
udp_socket.bind(("192.168.236.129", 7890))
# 3. 接受/发送 数据
# 接收数据
#客户端从缓存中获取数据,recvfrom的参数就是最大能接收的字节数,可以自己调整
# recvfrom获取的是 (msg, (ip, port))
recv_msg = udp_socket.recvfrom(1024)
# 发送数据,
# 第一个参数需要发送的信息,但必须是byte类型数据,所以字符串要编码encode;
# 第二个参数是元组类型,是ip+port,ip是字符串,端口是数字
udp_socket.sendto(msg.encode('utf-8'), ('192.168.236.130', 8080))
# 4. 关闭套接字
udp_socket.close()	
  1. tcp
    1. 工作原理描述:类似于打电话,知道收件方地址之后,先连接,接通后,才发送信息。
      因此,udp不安全

    2. tcp分为服务器和客户端,客户端访问服务器,有本机随机绑定端口,服务器需要绑定特定端口

客户端:

import socket
# 1. 创建电话机 -- tcp套接字
tcp_client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 2. 拨号 -- 连接服务器
tcp_client_socket.connect((server_ip, server_port)) 
# 3. 接受/发送 数据
# 发送数据,
# 参数需要发送的信息,但必须是byte类型数据,所以字符串要编码encode;
# 因为已经和服务器连接起来了,所以发送信息的时候不需要带服务器地址;
# 因此使用send函数,sendto函数是带地址的。
tcp_client_socket.send(msg.encode('utf-8'))
# 接收数据
#客户端从缓存中获取数据,recv的参数就是最大能接收的字节数,可以自己调整,获取的是byte类型数据
# recv函数获取的只有信息,recvfrom函数获取(msg, (ip, port))
recv_msg = tcp_client_socket.recv(1024)
# 4. 关闭套接字
tcp_client_socket.close()	

服务器:

import socket
# 1. 创建电话机 -- tcp套接字
tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 2. 绑定端口,bind的参数是元组,ip+port,ip是字符串,端口是数字
tcp_server_socket.bind(("192.168.236.129", 7890))
# 3. 设置为接听状态,listen参数128表示socket的排队数量为128个
tcp_server_socket.listen(128)
# 4. 有链接过来,产生一个专门的套接字,为这个客户端服务,使用accept函数
# accept函数产生阻塞,只有链接过来时,才能解阻塞
server_client_socket, server_client_addr = tcp_server_socket.accept()
# 5. 接受/发送 数据
# 接收数据
#客户端从缓存中获取数据,recv的参数就是最大能接收的字节数,可以自己调整
# recv函数获取的只有信息,recvfrom函数获取(msg, (ip, port))
recv_msg = server_client_socket.recv(1024)
# 发送数据,
# send函数参数是需要发送的信息,但必须是byte类型数据,所以字符串要编码encode;
# 使用send函数不带地址,sendto函数是带地址的。
server_client_socket.send(msg.encode('utf-8'))
# 4. 先关闭服务客户端的套接字,最后关闭服务器套接字
server_client_socket.close()
tcp_server_socket.close()  # 一般实际应用中服务器套接字是不会关闭的

服务器循环为多个客户端服务,且对单个客户端多次服务:

  1. 为多个客户端服务,即不停的在获取链接,即将accept函数写入死循环
  2. 为单个客户服务多次,即判断接受的信息是否为空,为空则表明客户端关闭,不为空则继续服务
import socket

tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcp_server_socket.bind(("192.168.236.129", 7890))
tcp_server_socket.listen(128)
# 1. 循环为多个客户端服务
while True:
	server_client_socket, server_client_addr = tcp_server_socket.accept()
	# 2. 循环为单个客户端服务
	while True:
		recv_msg = server_client_socket.recv(1024)
		print('客户端发送过来的请求是:%s'%recv_msg.decode("utf-8"))
		# 当客户端的套接字调用close后,服务器端会recv解堵塞,并且返回的长度为0;
		# 因此服务器可以通过返回数据的长度来区别客户端是否已经下线
		if recv_msg:
			server_client_socket.send(msg.encode('utf-8'))
		else:
			break
	server_client_socket.close()
  1. tcp与udp的联系与区别

     1. 联系:都是通信的一种方式。
     2. 区别:
     	1. udp通信方式就好比是写信;tcp通信方式就好比是打电话;
     	2. tcp的传输更安全可靠:
     		1. 报文发送应答机制:连接请求发送过去,会有同意请求或拒绝请求的信息返回;
     		2. 超时重传:请求发送过去一段时间后,没有收到返回信息,会重新再发送;
     		3. 错误校验:TCP用一个校验和函数来检验数据是否有错误;在发送和接收时都要计算校验;
     		4. 流量控制和阻塞管理 -- 流量控制用来避免主机发送得过快而使接收方来不及完全收下。
    

补充知识:

  1. 使用终端启动python文件时,可以通过终端输入的信息,给python文件传递参数;

      sys.args可以获取终端中除去python的参数,其余参数以元组形式呈现,(xxx.py, 7890)
    

终端:

python xxx.py port

python文件:

import sys
if len(sys_args) != 2:
	print("请按照如下方式运行:python3 xxx.py 7890")
	return
else:
	# 运行方式为python3 xxx.py 7890
	port = int(sys.argv[1])
  1. 解决端口复用
# setsockopt还可以设置缓存区大小;
# 参考:https://blog.csdn.net/chenggong2dm/article/details/9293427
# 参考:https://blog.csdn.net/rlenew/article/details/107592753
 tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值