网络通信:如今业界主流由udp通信和tcp通信,udp相对来说更加复杂一些,而tcp相对来说会更加的简单一些
我们首先先理解一下udp通信原理,和创建通信的必要步骤。
我们最常用的就是通过socket库来创建一个可运行的实现各主机之前收发文件。套接模板
import socket
def run():
#创建udp套接字
s =socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
#收发收据
#关闭套接字
s.close()
print("run.....")
if __name__ == '__main__':
run()
工程运行
from socket import *
#1 .创建套接字
upd_socket = socket(AF_INET,SOCK_DGRAM)
#2.目标主机
dest_addr =("192.168.23.143",8888) #注意是元组,ip是字符串,端口是数字
#3. 从键盘中获取数据
send_data =input("请输入要发送的内容:")
#4.发送到指定电脑的指定程序上去
upd_socket.sendto(send_data.encode("utf-8"),dest_addr)
#5. 关闭套接字
upd_socket.close()
如果是字符,变量就要加一个b 意思是字节流,如果是input输入,那么就必须要设置编码
循环发送数据
from socket import *
def main():
#1 .创建套接字
upd_socket = socket(AF_INET,SOCK_DGRAM)
while True:
#2.目标主机
dest_addr =("192.168.23.143",8888) #注意是元组,ip是字符串,端口是数字
#3. 从键盘中获取数据
send_data =input("请输入要发送的内容:")
if send_data =="exit":
break
#4.发送到指定电脑的指定程序上去
upd_socket.sendto(send_data.encode("utf-8"),dest_addr)
#5. 关闭套接字
upd_socket.close()
if __name__ == "__main__":
main()
对于socket我们一定要明确目的,先搭建框架,一共分为三步,1.创建套接字 2.连接远程主机IP 3.关闭套接字
以上是udp数据接收Ubuntu传入Windows,那么如何让通过socket让Windows发送数据,Ubuntu来进行接收呢
对于接收数据,我们一定要注意固定端口号才能进行网络的收发,这里我们需要指定端口号才行 。
from socket import *
"""
1.创建套接字
2.绑定一个本地信息
3.接收数据
4.打印接收到的数据
5.关闭套接字
"""
#1 .创建套接字
upd_socket = socket(AF_INET,SOCK_DGRAM)
#2.目标主机
dest_addr =(" ",8080) #注意是元组,ip是字符串,端口是数字
#3.绑定一个本地信息
upd_socket.bind(dest_addr)
#4. 等待接收对方发送的数据
recv =upd_socket.recvfrom(1024) #1024表示本次接收的的最大字节数
print(recv[0].decode("gbk"))
#5. 关闭套接字
upd_socket.close()
下面我们封装一下代码,增加一个可读性:
import socket
def main():
#1.创建套接字
udp_socket =socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
#2.绑定一个本地信息
localaddr =(" ",8080)
udp_socket.bind(localaddr)
#3.接收数据
recv_data =udp_socket.recvfrom(1024)
#4.打印接收到数据
print(recv_data)
udp_socket.close()
if __name__ == '__main__':
main()
升级(打印更加漂亮些)
import socket
def main():
#1.创建套接字
udp_socket =socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
#2.绑定一个本地信息
localaddr =(" ",8080)
udp_socket.bind(localaddr)
#3.接收数据
#经过运行可以发现recv_data这个变量中存储的是一个元组(接收到的数据,(发送方的IP,port))
recv_data =udp_socket.recvfrom(1024)
tmp = recv_data[0]#存储接收到的数据
send_ip =recv_data[1]#存储发送方的地址信息
#4.打印接收到数据
print("%s:%s"%(send_ip,tmp.decode("utf-8")))
udp_socket.close()
if __name__ == '__main__':
main()
但是这样存在一个问题,不能一直接收,那么如果我们要是想一直接受一下,那么就需要加一个循环,循环接收数据就可以很快乐地实现了
import socket
def main():
#1.创建套接字
udp_socket =socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
#2.绑定一个本地信息
localaddr =(" ",8080)
udp_socket.bind(localaddr)
#3.接收数据
#经过运行可以发现recv_data这个变量中存储的是一个元组(接收到的数据,(发送方的IP,port))
while True:
recv_data =udp_socket.recvfrom(1024)
tmp = recv_data[0]#存储接收到的数据
send_ip =recv_data[1]#存储发送方的地址信息
#4.打印接收到数据
print("%s:%s"%(send_ip,tmp.decode("utf-8")))
udp_socket.close()
if __name__ == '__main__':
main()
这里我们发现一个问题,我把程序杀死进程,重新开一个程序,就可以显示在一行,但是我把程序杀死进程重新开一个就会换行,这里我们发现端口不是固定的端口,是随机的端口(动态端口),是系统随机分配的一个端口,所以,每收发一条信息都要换行,因为端口的改变导致了换行,我们该如何解决这个问题呢
在前面绑定一个固定端口号就可以实现,如果程序终止了进程也同样可以实现指定端口号运行
localaddr =(" ",2420)
udp_socket.bind(localaddr)
收发信息功能:
import socket
def main():
# 1.创建udp套接字
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
dest_ip =input("请输入对方的IP:")
dest_port =int(input("请输入对方的port:"))
dest_input = input("请输入你要发送的内容:")
#发送信息
udp_socket.sendto(dest_input.encode("utf-8"),(dest_ip,dest_port))
#接受会送回来的数据
recv_data =udp_socket.recvfrom(1024)
#套接字可以同时收发
print(recv_data.decode("utf-8"))
#关闭套接字
udp_socket.close()
if __name__ == '__main__':
main()
单工: 收音机,只能收
半双工: 对讲机,可以收可以发,但是在收的时候不能发,在发的时候不能收
全双工:兼顾功能
socket套接字是全双工
项目实战:聊天器的实战:
import socket
def send_msg(udp_socket):
"""发送数据"""
send_ip = input("请输入对方的ip")
send_port = int(input("请输入端口:"))
send_data = input("请输入要发送的信息:")
udp_socket.sendto(send_data.encode("utf-8"), (send_ip, send_port))
def recv_msg(udp_socket):
"""接收数据"""
# 接收并显示
recv_data = udp_socket.recvfrom(1024)
tmp = recv_data[0] # 存储接收到的数据
send_ip = recv_data[1] # 存储发送方的地址信息
print("%s:%s" % (udp_socket, recv_data.decode("utf-8")))
def main():
#创建套接字
udp_socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
#绑定信息
udp_socket.bind(("",7788))
#循环来处理事情
while True:
print("-----聊天器----")
print("1.发送信息")
print("2.接收消息")
print("0 退出系统")
op =input("请输入功能:")
if op == "1":
send_msg(udp_socket)
#1.发送
#获取要发送的内容
elif op =="2":
#2.接收并显示
recv_msg(udp_socket)
elif op =="0":
break
else:
print("输入有误!")
if __name__ == '__main__':
main()
项目总结: 对于网络通信篇,我们更希望做的就是能够实现收发信息,对于python可以实现基本的功能。
写在最后:
1.信息接收完整代码及逻辑
import socket
def main():
#1.创建套接字
udp_socket =socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
#2.绑定一个本地信息
localaddr =(" ",8080)
udp_socket.bind(localaddr)
#3.接收数据
#经过运行可以发现recv_data这个变量中存储的是一个元组(接收到的数据,(发送方的IP,port))
while True:
recv_data =udp_socket.recvfrom(1024)
tmp = recv_data[0]#存储接收到的数据
send_ip =recv_data[1]#存储发送方的地址信息
#4.打印接收到数据
print("%s:%s"%(send_ip,tmp.decode("utf-8")))
udp_socket.close()
if __name__ == '__main__':
main()
2.信息发送完整代码及逻辑
from socket import *
def main():
#1 .创建套接字
upd_socket = socket(AF_INET,SOCK_DGRAM)
ip_input = input("请输入你输入目标ip地址:")
while len(ip_input)==0:
print("输入错误!")
break
while True:
print("输入exit退出!!!")
print("您的目标IP地址为%s"%ip_input)
#2.目标主机
dest_addr =(str(ip_input),8888) #注意是元组,ip是字符串,端口是数字
#3. 从键盘中获取数据
send_data =input("请输入要发送的内容:")
if send_data =="exit":
break
#4.发送到指定电脑的指定程序上去
upd_socket.sendto(send_data.encode("utf-8"),dest_addr)
#5. 关闭套接字
upd_socket.close()
if __name__ == "__main__":
main()
代码实现相对来说较为简单!