Python socket 编程

使用 Python37 调试

1.服务端

# -*- coding: UTF-8 -*-
import random
import socket

if __name__ == '__main__':

    s = socket.socket()  # 创建socket对象
    s.bind(('127.0.0.1', 123))  # 绑定地址和端口
    s.listen(5)  # 开始 TCP监听 参数5指定在拒绝连接之前,操作系统可以挂起的最大连接数量。该值至少为 1,大部分应用程序设为 5 就可以了。
    s.settimeout(50)  # 设置等待连接时间(秒),不设则永久等待
    while True:
        print('服务端开始监听')
        conn, address = s.accept()  # 有客户端访问了,返回的是连接对象和客户端地址,阻塞等待
        print('连接对象:{}'.format(conn))
        print('客户端地址:{}'.format(address))
        data = conn.recv(1024)  # bufsize 表示接收最大字节数,小于 bufsize 则全接收,大于 bufsize 则截断
        print('接收数据:{}'.format(data))
        print('数据类型:{}'.format(type(data)))  # Python37 接收到是 Bytes 型 Python27是 str
        msg = str(random.randint(0, 99999999)).encode('utf-8')
        conn.sendall(msg)  # 发送随机数给客户端
        print('服务端给客户端发送信息成功:{}'.format(msg))
    conn.close()  # 关闭连接
    print('服务端停止监听')

2.客户端

# -*- coding: UTF-8 -*-
import socket

if __name__ == '__main__':
    s = socket.socket()
    s.settimeout(10)  # 设置超时时间(连接或接收数据)
    s.connect(('127.0.0.1', 123))  # 连接服务端
    s.sendall('I am client data'.encode('utf-8'))  # 发送数据
    data = s.recv(1024)  # Python37 接收到是 Bytes 型 Python27是 str
    print('接收数据:{}'.format(data))
    print('type(data):{}'.format(type(data)))
    s.close()

运行

服务端

服务端开始监听
连接对象:<socket.socket fd=1412, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 123), raddr=('127.0.0.1', 53739)>
客户端地址:('127.0.0.1', 53739)
接收数据:b'I am client data'
数据类型:<class 'bytes'>
服务端给客户端发送信息成功:b'64716933'
服务端开始监听

客户端

接收数据:b'64716933'
type(data):<class 'bytes'>

3.异常情况

(1)[WinError 10054] 远程主机强迫关闭了一个现有的连接。

当客户端在接收数据时,服务端关闭(手动),则客户端抛出异常10054

当服务端在接收数据时,客户端关闭(手动),则服务端抛出异常10054

手动指的是自己关闭了运行的cmd

(2)[WinError 10061] 由于目标计算机积极拒绝,无法连接。

当客户端连接服务端时,使用了错误的PORT,客户端抛出异常10061

当客户端连接服务端时,使用了错误的IP,客户端抛出异常10061

(3)[WinError 10048] 通常每个套接字地址(协议/网络地址/端口)只允许使用一次。

当服务端绑定了一个IP和PORT, 再次绑定时,服务端抛出异常10048

(4)[WinError 10053] 你的主机中的软件中止了一个已建立的连接。

当客户端在接收数据时,服务端关闭(自动),则客户端抛出异常10053

自动指的是代码自动调用到s.close()

该代码可复现

# -*- coding: UTF-8 -*-
import random
import socket
import time

if __name__ == '__main__':

    s = socket.socket()  # 创建socket对象
    s.bind(('127.0.0.1', 123))  # 绑定地址和端口
    s.listen(5)  # 开始 TCP监听 参数5指定在拒绝连接之前,操作系统可以挂起的最大连接数量。该值至少为 1,大部分应用程序设为 5 就可以了。
    s.settimeout(50)  # 设置等待连接时间(秒),不设则永久等待
    while True:
        print('服务端开始监听')
        conn, address = s.accept()  # 有客户端访问了,返回的是连接对象和客户端地址,阻塞等待
        print('连接对象:{}'.format(conn))
        print('客户端地址:{}'.format(address))
        data = conn.recv(1024)  # bufsize 表示接收最大字节数,小于 bufsize 则全接收,大于 bufsize 则截断
        print('接收数据:{}'.format(data))
        print('数据类型:{}'.format(type(data)))  # Python37 接收到是 Bytes 型 Python27是 str
        msg = str(random.randint(0, 99999999)).encode('utf-8')
        conn.sendall(msg)  # 发送随机数给客户端
        print('服务端给客户端发送信息成功:{}'.format(msg))
        break
    conn.close()  # 关闭连接
    print('服务端停止监听')
# -*- coding: UTF-8 -*-
import socket
import time

if __name__ == '__main__':
    s = socket.socket()
    # s.settimeout(5)  # 设置超时时间(连接或接收数据)
    s.connect(('127.0.0.1', 123))  # 连接服务端
    # time.sleep(5)
    while True:
        s.sendall('I am client data'.encode('utf-8'))  # 发送数据
        data = s.recv(1024)  # Python37 接收到是 Bytes 型 Python27是 str
        print('接收数据:{}'.format(data))
        print('type(data):{}'.format(type(data)))
        time.sleep(10)
    s.close()

运行

服务端

服务端开始监听
连接对象:<socket.socket fd=1432, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 123), raddr=('127.0.0.1', 56007)>
客户端地址:('127.0.0.1', 56007)
接收数据:b'I am client data'
数据类型:<class 'bytes'>
服务端给客户端发送信息成功:b'36744020'
服务端停止监听

客户端

 

posted @ 2019-08-15 15:41  南风丶轻语  阅读(253)  评论(0编辑  收藏  举报