【网络编程】

目录

一、UDP编程

二、TFTP文件下载器

三、TCP编程

一、UDP编程

UDP传输方式类似于发送短信,使用这种方式进行网络通讯时,不需要建立专门的虚拟连接,传输也不是很可靠,如果发送失败则客户端无法获得,因此大量的非核心数据可以通过UDP方式进行传递

1.数据的接收与发送

'''
from socket import socket,AF_INET,SOCK_DGRAM
#创建套接字
udp_socket=socket(AF_INET,SOCK_DGRAM)
#创建接收信息的地址
add=('112.32.173.157',8080)
#键盘接收发送的消息
data=input('输入要发送的信息')
#调用sendto方法发送信息
udp_socket.sendto(data.encode('gb2312'),add)
#关闭套接字
udp_socket.close()
'''
from socket import *
#创建UDP套接字
udp_socket=socket(AF_INET,SOCK_DGRAM)
#绑定一个端口
udp_socket.bind(('',8989))
add=('112.32.173.157',8080)
data=input('请输入要发送的信息')
#发送数据
udp_socket.sendto(data.encode('gb2312'),add)
recev_data=udp_socket.recvfrom(1024) #本次接收最大字节数为1024
print('接收到的信息是:%s'%(recev_data[1],recev_data[0].decode('gb2312')))
#关闭套接字
udp_socket.close()

 2.UDP使用多线程实现聊天

#导入模块
from socket import *
from threading import Thread
#创建UDP套接字对象
udp_socket=socket(AF_INET,SOCK_DGRAM)
#绑定本机与端口
udp_socket.bind(('', 8889)) #单引号代表本机
#接收
def recv_fun():
    while True:
        recv_data=udp_socket.recvfrom(1024)
        print('>>%s:%s' % (recv_data[1], recv_data[0].decode('gb2312')))
#decode:字节转换成字符串
#发送
def send_fun():
    while True:
        add=('112.32.173.157', 8080)
        data=input('<<:')
        udp_socket.sendto(data.encode('gb2312'), add)


if __name__ == '__main__':
    # 创建两个线程
    t1=Thread(target=send_fun)
    t2=Thread(target=recv_fun)
    t1.start()
    t2.start()
    t1.join()
    t2.join()

二、TFTP文件下载器

利用struck模块相关方法完成下载:

函数描述
pack(fmt, v1, v2..)按照给定的格式(fmt),把数据封装成字符串(实际上是类似于c结构体的字节流)
unpack(fmt, string)按照给定的格式(fmt)解析字节流string,返回解析出来的元组
calcsize(fmt)计算给定的格式(fmt)占用多少字节的内存
#导入模块
import struct
from socket import *
filename='cat.png'
server_ip='112.32.173.157' #本地ip
#封装读请求
send_data=struct.pack('!H%dsb5sb' % len(filename), 1, filename.encode(), 0, 'octet'.encode(), 0)
#创建udp_socket套接字
udp_socket=socket(AF_INET, SOCK_DGRAM)
#将数据发送,读写端口默认为69
udp_socket.sendto(send_data, (server_ip, 69))
#在本地创建一个文件
f=open((filename,'ab')) #a表示追加模式,b表示二进制
while True:
    recv_data=udp_socket.recvfrom(1024)
    print(recv_data)
    #获取操作码及数据块编号
    caozuoma,ack_num=struct.unpack('!HH', recv_data[0][:4])
    #判断操作码是否是5 如果是5,则是错误信息
    if caozuoma == 5:
        print('文件不存在')
        break
    #将接收到的数据写入到文件中
    f.write(recv_data[0][4:])
    if len(recv_data[0]) < 516: #表示读取完毕
        break
    #发送确认包
    ack_data=struct.pack('!HH',4,ack_num)
    #获取服务器发送数据的随机端口
    rand_port=recv_data[1][1]
    udp_socket.sendto(ack_data,(server_ip,rand_port))

三、TCP编程

TCP方式就类似于拨打电话,使用该种方式进行网络通讯时,需要建立专门的虚拟连接,然后进行可靠的数据传输,如果数据发送失败,则客户端会自动重发该数据,因此重要的数据一般使用TCP方式进行数据传输

1.数据的发送与接收

'''
#服务器端
from socket import *
#创建服务器端套接字
server_socket=socket(AF_INET,SOCK_STREAM)
#绑定端口
server_socket.bind(('',8888))
#监听是否有数据发送过来
server_socket.listen()
#接收客户端连接
client_socket,client_info=server_socket.accept()
#接收客户端发送的消息
recv_data=client_socket.recv(1024)
print("接收到%s的消息%s"%(client_info,recv_data.decode('gd2312')))
#关闭连接
client_socket.close()
server_socket.close()
'''
#双向通信,服务器端
from socket import *
#创建服务器端套接字
server_socket=socket(AF_INET,SOCK_STREAM)
#绑定端口
server_socket.bind(('',8888))
#监听是否有数据发送过来
server_socket.listen()
#等待客户端连接
client_socket,client_info=server_socket.accept()
while True:
    # 接收客户端发送的消息
    recv_data = client_socket.recv(1024)
    print('客户端:',recv_data.decode('utf-8'))
    #发送消息
    msg=input('>>:')
    client_socket.send(msg.encode('utf-8'))
#客户端
from socket import *
#创建客户器端套接字
client_socket=socket(AF_INET,SOCK_STREAM)
#调用方法与服务器建立连接
client_socket.connect(('112.32.173.157',8888))
while True:
    #客户端发送信息
    msg=input('>>:')
    client_socket.send(msg.encode('utf-8'))
    #客户端接收消息
    recv_data=client_socket.recv(1024)
    print("服务器端说:",recv_data.decode('utf-8'))
client_socket.close()
server_socket.close()

2.使用多线程进行通信

#服务器端
from socket import *
from threading import Thread
sockets=[]
def main():
    #创建服务器端套接字
    server_socket=socket(AF_INET,SOCK_STREAM)
    #绑定端口
    server_socket.bind(('',8888))
    #监听是否有数据发送过来
    server_socket.listen()
    #接收客户端请求
    while True:
        client_socket,client_info=server_socket.accept()
        sockets.append(client_socket)
        #开启线程处理当前客户端的请求
        t=Thread(target=readMsg)
        t.start()
def readMsg(client_socket):
    #读取客户端的消息
    while True:
        recv_data=clien_socket.recv(1024)
        #将消息发送给所有在线客户端
        #遍历所有在线客户端列表
        for socket in sockets:
            socket.send(recv_data)
if __name__=="__main__":
    main()
#客户端
from socket import *
from threading import Thread
def readMsg(client_socket):
    while True:
        recv_data=client_socket.recv(1024)
        print("收到:",recv_data.decode('utf_8'))
def writeMsg(client_socket):
    while True:
        msg=input(">>:")
        client_socket.send(msg.encode('utf_8'))
#创建客户端套接字
client_socket=socket(AF_INET,SOCK_STREAM)
#调用方法连接服务器
client_socket.connect(('112.32.173.157',8888))
#开启一个线程处理客户端的读取消息
t=Thread(target=readMsg,args=(client_socket,))
t.start()
#开启一个线程处理客户端的发送消息
t=Thread(target=writeMsg,args=(client_socket,))
t.start()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

In my opinion

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值