python Socket无限发送接收数据

一、关于Socket

1.Socket简介

Socket是指套接字,是对网络中不同主机上的应用进程之间进行双向通信的端点的一种抽象。一个套接字就是网络上进程通信的一端,提供了应用层进程利用网络协议交换数据的机制。

2.Socket的主要类型

Socket主要有三种类型:流套接字、数据报套接字、原始套接字。

流套接字(SOCK_STREAM):采用了TCP协议,用于提供面向连接、可靠的数据传输服务。

数据报套接字(SOCK_DGRAM):采用了UDP协议,提供一种无连接的服务。该服务并不能保证数据传输的可靠性,数据有可能在传输过程中丢失或出现数据重复,且无法保证顺序地接收到数据。

原始套接字(SOCK_RAW):与上面两种套接字的区别在于原始套接字可以读写内核没有处理的IP数据包,而流套接字只能读取TCP协议的数据,数据报套接字只能读取UDP协议的数据。

本文中讲的是采用TCP协议,即流套接字。

二、Python的socket模块

Python中进行网络编程的主要是使用socket模块,当然还有高级一点的网络服务模块SocketServer等内容。本文中主要使用的是socket模块。

socket模块中首先需要使用socket()方法创建套接字对象,代码示例如下:

python 复制代码
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

其中,第一个参数是代表套接字家族,一般有socket.AF_UNIX、socket.AF_INET、socket.AF_INET6可以选择。AF_UNIX是本机的通信,AF_INET和AF_INET6分别是IPv4和IPv6。

第二个参数是套接字类型,有socket.SOCK_STREAM、socket.SOCK_DGRAM、socket.SOCK_RAW,分别代表套接字的三种类型。

三、Socket服务端和客户端相关函数

1.服务端使用的函数

函数 描述
s.bind() 绑定地址(host,port)到套接字, 在 AF_INET下,以元组(host,port)的形式表示地址
s.listen() 开始 TCP 监听。参数backlog是指操作系统可以挂起的最大连接数量。该值至少为 1,一般设置为5
s.accept() 被动接受TCP客户端连接,阻塞式等待连接的到来

2.客户端使用的函数

函数 描述
s.connect() TCP服务器连接,参数address的格式为元组(hostname,port),如果连接出错,返回socket.error错误。
s.connect_ex() connect()函数的扩展版本,出错时返回出错码,而不是抛出异常

3.服务端和客户端都可以使用的函数

函数 描述
s.recv() 接收 TCP 数据,数据以字符串形式返回,bufsize 指定要接收的最大数据量
s.send() 发送 TCP 数据,将参数string 中的数据发送到连接的套接字
s.sendall() 完整发送 TCP 数据。将参数 string 中的数据发送到连接的套接字,但在返回之前会尝试发送所有数据。成功返回 None,失败则抛出异常。
s.close() 关闭套接字
s.getpeername() 返回连接套接字的远程地址。返回值通常是元组(ipaddr,port)
s.getsockname() 返回套接字自己的地址。通常是一个元组(ipaddr,port)
s.setsockopt() 设置给定套接字选项的值
s.getsockopt() 返回套接字选项的值
s.settimeout() 设置套接字操作的超时期,参数timeout是一个浮点数,单位是秒。值为None表示没有超时期
s.gettimeout() 返回当前超时期的值,单位是秒,如果没有设置超时期,则返回None
s.setblocking() 如果参数flag为0,则将套接字设为非阻塞模式,否则将套接字设为阻塞模式(默认值)。非阻塞模式下,如果调用recv()没有发现任何数据,或send()调用无法立即发送数据,那么将引起socket.error异常

四、服务器端代码

python 复制代码
import socket

def socket_server():
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    ip = ''   # ip可以是127.0.0.1,也可以为空
    port = 0000   # 端口号
    server_socket.bind((ip, port))
    server_socket.listen(5)
    logger.info('等待连接')
    while True:
        try:
            client_socket, address = server_socket.accept()
            logger.info(address[0] + '已连接')
            while True:
                data = client_socket.recv(1024)   # 接受客户端发来的数据
                if not data:
                    logger.info(address[0] + '断开连接')
                    break
                client_socket.send(data.upper())
                """
                可以使用else与上面的if形成搭配
                自己的任意想要实现的功能
				"""
        except ConnectionResetError:
            logger.error(address[0] + '异常断开连接')
            continue
        except KeyboardInterrupt:
            logger.info('服务器关闭')
            break
    server_socket.close()

if __name__ == '__main__':
    socket_server()

五、客户端代码

python 复制代码
import socket

def socket_client():
    client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    ip = ''   # ip可以为127.0.0.1,也可以为服务器的IP,例:10.0.0.xxx
    port = 0000   # 必须与服务器端口号一致
    client_socket.connect((ip, port))

    while True:
        msg = input('>>').strip()
        if not msg:
            continue
        client_socket.send(msg.encode('utf-8'))   # 客户端发送数据
        data = client_socket.recv(1024)   # 接收服务端返回的数据
        print(data.decode("utf-8"))
        # break   无break可以循环发送

    client_socket.close()

if __name__ == '__main__':
    socket_client()

注:客户端和服务端再接收发送数据时,都需要注意数据格式,即decode()和encode()。

相关推荐
Code out the future6 分钟前
【C++——临时对象,const T&】
开发语言·c++
taoyong00110 分钟前
Java线程核心01-中断线程的理论原理
java·开发语言
一雨方知深秋11 分钟前
智慧商城:封装getters实现动态统计 + 全选反选功能
开发语言·javascript·vue2·foreach·find·every
海威的技术博客13 分钟前
关于JS中的this指向问题
开发语言·javascript·ecmascript
觅远15 分钟前
python实现word转html
python·html·word
froginwe1139 分钟前
PostgreSQL表达式的类型
开发语言
悠然的笔记本41 分钟前
python2和python3的区别
python
委婉待续42 分钟前
java抽奖系统(八)
java·开发语言·状态模式
deja vu水中芭蕾44 分钟前
嵌入式C面试
c语言·开发语言
爱码小白44 分钟前
PyQt5 学习方法之悟道
开发语言·qt·学习方法