Python3网络编程

TCP编程

TCP/IP介绍:https://www.cnblogs.com/onepixel/p/7092302.html

客户端

大多数连接都是可靠的TCP连接。创建TCP连接时,主动发起连接的叫客户端,被动响应连接的叫服务器。我们要创建一个基于TCP连接的Socket,可以这样做:

import socket
import threading
import time


def tcp_link(sock, addr):
    """
    每个连接都必须创建新线程(或进程)来处理,否则,单线程在处理连接的过程中,无法接受其他客户端的连接
    连接建立后,服务器首先发一条欢迎消息,然后等待客户端数据,并加上Hello再发送给客户端。
    如果客户端发送了exit字符串,就直接关闭连接。
    """
    print('Accept new connection from %s:%s...' % addr)
    sock.send(b'Welcome!')
    while True:
        data = sock.recv(1024)  # 一次接收1024个字节的信息
        time.sleep(1)
        if not data or data.decode('utf-8') == 'exit':
            break
        sock.send(('Hello, %s!' % data.decode('utf-8')).encode('utf-8'))
    sock.close()
    print('Connection from %s:%s closed.' % addr)


if __name__ == '__main__':
    # 创建一个基于IPv4和TCP协议的Socket
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    # 绑定监听的地址和端口
    s.bind(('127.0.0.1', 9999))

    # 调用listen()方法开始监听端口,传入的参数指定等待连接的最大数量
    s.listen(5)
    print('Waiting for connection...')

    # 服务器程序通过一个永久循环来接受来自客户端的连接,accept()会等待并返回一个客户端的连接
    while True:
        # 接受一个新连接:
        sock, addr = s.accept()
        # 创建新线程来处理TCP连接:
        t = threading.Thread(target=tcp_link, args=(sock, addr))
        # 开启线程
        t.start()

然后我们开启服务器:

image.png

编写一个客户端程序:

import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 建立连接:
s.connect(('127.0.0.1', 9999))
# 接收欢迎消息:
print(s.recv(1024).decode('utf-8'))
for data in [b'Michael', b'Tracy', b'Sarah']:
    # 发送数据:
    s.send(data)
    print(s.recv(1024).decode('utf-8'))
s.send(b'exit')
s.close()

运行客户端程序:

image.png

同时服务端响应:

image.png

UDP编程

TCP是建立可靠连接,并且通信双方都可以以流的形式发送数据。相对TCP,UDP则是面向无连接的协议。

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

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

编写服务端:

import socket

# 创建一个基于IPv4和UDP协议的Socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

# 绑定监听的地址和端口
s.bind(('127.0.0.1', 9999))

# 不需要调用listen()方法,而是直接接收来自任何客户端的数据
print('Bind UDP on 9999...')
while True:
    """
    接收数据:
    recvfrom()方法返回数据和客户端的地址与端口,
    这样,服务器收到数据后,直接调用sendto()就可以把数据用UDP发给客户端。
    """
    data, addr = s.recvfrom(1024)
    print('Received from %s: %s.' % (addr, data))
    s.sendto(b'Hello, %s!' % data, addr)

开启服务端:

image.png

编写客户端:

import socket

# 客户端使用UDP时,首先仍然创建基于UDP的Socket,然后,不需要调用connect(),直接通过sendto()给服务器发数据
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
for data in [b'Michael', b'Tracy', b'Sarah']:
    # 发送数据:
    s.sendto(data, ('127.0.0.1', 9999))
    # 接收数据:
    print(s.recv(1024).decode('utf-8'))
s.close()

开启客户端:

同时服务端进行响应:

image.png

注意这里省掉了多线程,因为这个例子很简单。

你可能感兴趣的:(Python3网络编程)