socket TCP/UDP

1.socket是什么?
是电脑网络中进程间数据流的端点
操作系统的通信机制
应用程序通过socket进行网络数据的传输

2.通信过程与TCP三次握手相似

3.socket通信方式
分为:UDP和TCP

4.socket参数
type:类型
socket.SOCK_STREAM 流式socket,for TCP(默认)
socket.SOCK_DGRAM 数据报式socket,for UDP
socket.SOCK_RAW 原始套接字 (可以忽略)
socket.SOCK_RDM 可靠UDP形式 (可以忽略)
socket.SOCK_SEQPACKET 可靠的连续数据包服务 (可以忽略)

创建服务器

import random
import socket

# 创建实例
sk = socket.socket()
# 定义绑定的ip和端口
ip_port = ('127.0.0.1',8888) # 元祖
# 绑定监听
sk.bind(ip_port)

# 最大连接数
sk.listen(5) # 最少是1
# 5代表 挂起的连接数是5,同时有5个请求来,
# 可以同时回应,正在处理的程序只有一个,其他4个程序处于等待状态
# 如果多于5个服务器会直接拒绝第六个请求

# 不断接受数据
while True:
    # 提示信息
    print('正在接受 数据.......')

    # 接受数据:传回两个参数一个是连接对象,一个是客户端地址
    # 接受数据是阻塞状态
    conn,address = sk.accept()
    # 定义信息
    msg = '连接成功'
    # 返回信息
    """
    注意:
        python3.x以上,网络数据的发送接受都是byte类型
        如果发送的数据是str型的则需要进行编码,python2 不需要
    """
    conn.send(msg.encode())

    # 不断接受客户端发来的消息
    while True:
        # 接受客户端消息
        data = conn.recv(1024) # 接受1024字节
        # 打印数据
        print(data.decode())
        # 接受到退出指令
        if data == b'exit':
            break
        # 处理客户端数据
        conn.send(data)
        # 发送随机数信息
        conn.send(str(random.randint(1,1000)).encode())

    # 直接连接的关闭,主动关闭连接
    # 通信一次就关闭
    conn.close()

创建客户端

import socket

# 实例的初始化
client = socket.socket()

# 访问的服务器端的ip和端口
ip_port = ('127.0.0.1',8888)

# 连接主机
client.connect(ip_port)


while True:
    # 连接主机信息
    data = client.recv(1024)  # 接受数据为1024个字节

    # 打印接收到的数据
    # 此处的byte型数据特指python3.x以上 ,py2不用
    print(data.decode())
    # 输入发送的消息
    msg_input = input('请输入发送的消息:')
    # 消息发送
    client.send(msg_input.encode())
    if msg_input == 'exit':
        break


    data = client.recv(1024)
    print(data.decode())

UDP

socket_server_udp
import socket

# 创建实例
sk = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) # 不指定参数默认ipv4、tcp流式发送方式

# 定义绑定的ip和port
ip_port = ('127.0.0.1',7888)

# 绑定监听
sk.bind(ip_port)

# 不断循环接受数据
while True:
    # 接受数据
    data = sk.recv(1024)
    # 打印数据
    print(data.decode())

# UDP的server并没有关闭连接的方法,因为UDP是一种不可靠的通信方式
# 之间并不进行三次握手过程
# UDP的通信方式:
# 服务器接受客户端的数据,并进行客户端的发送。服务器端接受客户端的和数据并根据需要返回给客户端
# 同时,并不与客户端建立安全的通道,保证数据包的安全通信

socket_client_udp
import socket

# 定义实例
sk = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)

# 定义需要连接的服务器ip和port
ip_port = ('127.0.0.0.1', 7888)

# 循环数据的输入
while True:
    # 输入发送的信息
    msg_input = input('请输入发送的消息:')
    # 退出循环的条件
    if msg_input == 'exit':
        break

    # 数据发送
    sk.sendto(msg_input.encode(), ip_port)

# 发送关闭信息(主动发送)
sk.close()

socket非阻塞模块

服务器端对多个客户端连接

import random
import socketserver

# 定义一个类
class MyServer(socketserver.BaseRequestHandler):
    # 这三个方法是系统自带的
    # 通过自己定义的类,去进行三个方法的定义,以覆盖原来的方法
    # 执行顺序setup,handle,finish
    # 如果handle方法出现报错,则会进行跳过
    # setup方法和finish方法无论如何都会执行的
    # 一般情况下不去进行定义setup方法和finish方法,只会对handle方法的重写
    def setup(self):
        pass

    def handle(self):
        # 定义连接变量
        conn = self.request
        # 发送信息定义
        msg = 'Hello world'
        # 信息发送
        conn.send(msg.encode())
        # 进入循环,不断接受客户端的消息
        while True:
            # 接受客户端消息
            data = conn.recv(1024*64)
            # 打印消息
            print(data.decode())
            # 接受exit 则进行循环退出
            if data == 'exit':
                break
            conn.send(data)
            conn.send(str(random.randint(1,1000)).encode())
            conn.close()


    def finish(self):
        pass


if __name__ == '__main__':
    # 创建多线程实例
    # 传入监听的ip、端口,和自己定义的类
    server = socketserver.ThreadingTCPServer(('127.0.0.1',8888),MyServer)
    # 开启异步多线程,等待客户端的连接
    # server.handle_request() 只处理一个请求
    server.serve_forever()  # 处理多个请求,永远执行


文件上传

文件接收.py

import socket

sk = socket.socket()

ip_port = ('127.0.0.1',8999)
sk.bind(ip_port)

sk.listen(5)
while True:
    # 等待客户端连接
    conn,address = sk.accept()
    # 一直使用当前连接数据发送
    # 直到结束标志出现
    while True:
        with open('file', 'ab') as f:
            # 接收数据
            data = conn.recv(1024)
            if data == b'quit':
                break
            # 写入文件
            f.write(data)
            # 接收完成标志
            conn.send('success'.encode())
    # 打印提示信息
    print('文件接收完成')
# 关闭连接
sk.close() # 没有生效

文件上传.py

import socket

sk = socket.socket()

ip_port = ('127.0.0.1',8999)
sk.connect(ip_port)

# 文件上传
# 打开文件
with open('socket_server_tcp2.py','rb') as f:
    # 按每一段分隔文件
    for i in f:
        # 数据上传
        sk.send(i)

        data = sk.recv(1024)
        if data != b'success':
            break
# 给服务器端发送结束信号
sk.send('quit'.encode())

你可能感兴趣的:(socket TCP/UDP)