网络编程之UDP

Posted pangqian

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了网络编程之UDP相关的知识,希望对你有一定的参考价值。

大文件上传

服务端
import json
import struct


server = socket.socket()
server.bind((‘127.0.0.1‘,8080))
server.listen(5)

while True:
    conn,addr = server.accept()
    while True:
        try:
            header_len = conn.recv(4)
            # 解析字典报头
            header_len = struct.unpack(‘i‘,header_len)[0]
            # 再接收字典数据
            header_dic = conn.recv(header_len)
            real_dic = json.loads(header_dic.decode(‘utf-8‘))
            # 获取数据长度
            total_size = real_dic.get(‘file_size‘)
            # 循环接收并写入文件
            recv_size = 0
            with open(real_dic.get(‘file_name‘),‘wb‘) as f:
                while recv_size < total_size:
                    data = conn.recv(1024)
                    f.write(data)
                    recv_size += len(data)
                print(‘上传成功‘)
        except ConnectionResetError as e:
            print(e)
            break
    conn.close()
客户端
import socket
import json
import os
import struct

client = socket.socket()
client.connect((‘127.0.0.1‘,8080))

while True:
    MOVIE_DIR = r‘E:\视频‘
    movie_list = os.listdir(MOVIE_DIR)
    for i,movie in enumerate(movie_list,1):
         print(i,movie)

    choice = input(‘please choice movie to upload>>>:‘)
    if choice.isdigit():
        choice = int(choice) - 1
        if choice in range(0,len(movie_list)):
            path = movie_list[choice]
            file_path = os.path.join(MOVIE_DIR,path)
            file_size = os.path.getsize(file_path)
            res_d =
                ‘file_name‘:‘甄嬛传.mp4‘,
                ‘file_size‘:file_size,
                ‘msg‘:‘注意身体,多喝热水!‘
            
            json_d = json.dumps(res_d)
            json_bytes = json_d.encode(‘utf-8‘)

            header = struct.pack(‘i‘,len(json_bytes))
            client.send(header)
            client.send(json_bytes)
            with open(file_path,‘rb‘)as f:
                for line in f:
                    client.send(line)
        else:
            print(‘not in range‘)
    else:
        print(‘must be a number‘)

 异常处理

异常处理分成两种:

一种是语法错误,这种错误没办法过python解释器的语法检测,必须在发生之后就改正 

#语法错误示范一
if
#语法错误示范二
def test:
    pass
#语法错误示范三
class Foo
    pass
#语法错误示范四
print(haha

  

还有一种是逻辑错误,这种错误看不出来,可以采用异常处理机制进行捕获

#TypeError:int类型不可迭代
for i in 3:
    pass
#ValueError
num=input(">>: ") #输入hello
int(num)

#NameError
aaa

#IndexError
l=[‘egon‘,‘aa‘]
l[3]

#KeyError
dic=‘name‘:‘egon‘
dic[‘age‘]

#AttributeError
class Foo:pass
Foo.x

#ZeroDivisionError:无法完成计算
res1=1/0
res2=1+‘str‘

 

异常种类

AttributeError 试图访问一个对象没有的树形,比如foo.x,但是foo没有属性x
IOError 输入/输出异常;基本上是无法打开文件
ImportError 无法引入模块或包;基本上是路径问题或名称错误
IndentationError 语法错误(的子类) ;代码没有正确对齐
IndexError 下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5]
KeyError 试图访问字典里不存在的键
KeyboardInterrupt Ctrl+C被按下
NameError 使用一个还未被赋予对象的变量
SyntaxError Python代码非法,代码不能编译(个人认为这是语法错误,写错了)
TypeError 传入对象类型与要求的不符合
UnboundLocalError 试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量,
导致你以为正在访问它
ValueError 传入一个调用者不期望的值,即使值的类型是正确的

避免发生错误,需要用到try...except:在错误发生之后进行处理

#基本语法为
try:
    被检测的代码块
except 异常类型:
    try中一旦检测到异常,就执行这个位置的逻辑
#举例
try:
    f=open(‘a.txt‘)
    g=(line.strip() for line in f)
    print(next(g))
    print(next(g))
    print(next(g))
    print(next(g))
    print(next(g))
except StopIteration:
    f.close()

 

#1 异常类只能用来处理指定的异常情况,如果非指定异常则无法处理。
s1 = hello
try:
    int(s1)
except IndexError as e: # 未捕获到异常,程序直接报错
    print e

#2 多分支
s1 = hello
try:
    int(s1)
except IndexError as e:
    print(e)
except KeyError as e:
    print(e)
except ValueError as e:
    print(e)

#3 万能异常Exception
s1 = hello
try:
    int(s1)
except Exception as e:
    print(e)

#4 多分支异常与万能异常
#4.1 如果你想要的效果是,无论出现什么异常,我们统一丢弃,或者使用同一段代码逻辑去处理他们,那么骚年,大胆的去做吧,只有一个Exception就足够了。
#4.2 如果你想要的效果是,对于不同的异常我们需要定制不同的处理逻辑,那就需要用到多分支了。

#5 也可以在多分支后来一个Exception
s1 = hello
try:
    int(s1)
except IndexError as e:
    print(e)
except KeyError as e:
    print(e)
except ValueError as e:
    print(e)
except Exception as e:
    print(e)

#6 异常的其他机构
s1 = hello
try:
    int(s1)
except IndexError as e:
    print(e)
except KeyError as e:
    print(e)
except ValueError as e:
    print(e)
#except Exception as e:
#    print(e)
else:
    print(try内代码块没有异常则执行我)
finally:
    print(无论异常与否,都会执行该模块,通常是进行清理工作)

#7 主动触发异常
try:
    raise TypeError(类型错误)
except Exception as e:
    print(e)

#8 自定义异常
class EgonException(BaseException):
    def __init__(self,msg):
        self.msg=msg
    def __str__(self):
        return self.msg

try:
    raise EgonException(类型错误)
except EgonException as e:
    print(e)

#9 断言:assert 条件
assert 1 == 1  
assert 1 == 2

#10 总结try..except

1:把错误处理和真正的工作分开来
2:代码更易组织,更清晰,复杂的工作任务更容易实现;
3:毫无疑问,更安全了,不至于由于一些小的疏忽而使程序意外崩溃了;

 

UDP

UDP则是面向无连接的协议。

数据包就是这种形式。比如:短信。只要数据发送出去。无需去管对方是否接收到。

使用UDP协议时,不需要建立连接,只需要知道对方的IP地址和端口号,就可以直接发数据包。但是,能不能到达就不知道了。

虽然用UDP传输数据不可靠,但它的优点是和TCP比,速度快,对于不要求可靠到达的数据,就可以使用UDP协议。

我们来看看如何通过UDP协议传输数据。和TCP类似,使用UDP的通信双方也分为客户端和服务器。服务器首先需要绑定端口:

服务器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# -*- coding: utf-8 -*-
import socket
 
‘‘‘
使用UDP协议时,不需要建立连接,只需要知道对方的IP地址和端口号,就可以直接发数据包。但是,能不能到达就不知道了。
 
虽然用UDP传输数据不可靠,但它的优点是和TCP比,速度快,对于不要求可靠到达的数据,就可以使用UDP协议。
 
我们来看看如何通过UDP协议传输数据。和TCP类似,使用UDP的通信双方也分为客户端和服务器。服务器首先需要绑定端口
绑定端口和TCP一样,但是不需要调用listen()方法,而是直接接收来自任何客户端的数据
‘‘‘
# ipv4        SOCK_DGRAM指定了这个Socket的类型是UDP
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 绑定 客户端口和地址:
s.bind((127.0.0.1, 9999))
print Bind UDP on 9999...
while True:
    # 接收数据 自动阻塞 等待客户端请求:
    data, addr = s.recvfrom(1024)
    print Received from %s:%s. % addr
    s.sendto(Hello, %s! % data, addr)
#recvfrom()方法返回数据和客户端的地址与端口,这样,服务器收到数据后,直接调用sendto()就可以把数据用UDP发给客户端。
  客户端:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# -*- coding: utf-8 -*-
 
import socket
 
‘‘‘
客户端使用UDP时,首先仍然创建基于UDP的Socket,然后,不需要调用connect(),直接通过sendto()给服务器发数据:
‘‘‘
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
 
for data in [a, b, c]:
    # 发送数据:
    s.sendto(data, (127.0.0.1, 9999))
    # 接收数据:
    print s.recv(1024)
s.close()

 

以上是关于网络编程之UDP的主要内容,如果未能解决你的问题,请参考以下文章

Java网络编程编程之TCP编程和UDP编程

基于UDP协议之——socket编程

Java网络编程之UDP和TCP套接字

UDP之socket编程

Python之UDP编程

网络骇客入门之UDP编程