抽象出来的socketsokcet的工作流程模块编程参数详解

什么是套接字?

Socket,又称“socket”,是一套基于TCPP协议封装的编程接口。它通常称为套接字,但请记住这一点。

Socket 隐藏了底层复杂 TCP 协议的各种细节,并将其封装成简单可操作的编程 API 接口,提高开发者编写网络通信软件的开发效率。

如果你想写qq、微信这样的C/S架构的通讯软件,可以用Socket代替写原生TCP/IP协议的底层。

注意,Socket本身并不是一个协议,它是应用层和TCP/IP协议族之间通信的中间件抽象层,以及一组调用接口。

抽象套接字

sokcet的工作流程

只在服务端使用的socket函数的socket模块编程参数详解

s.bind() 将主机端口号绑定到套接字

s.listen() 开始tcp监听

s.accept() 被动接受客户端的连接,(阻塞)等待连接的到来

客户端套接字函数

c.connect() 主动初始化tcp服务器连接

c.connect_ex() connect() 函数的扩展版本,在出错时返回错误代码而不是抛出异常

公用socket函数

s.recv 接收tcp数据

s.send() 发送tcp数据,它会返回已经发送的数据量,如果只发送了部分数据,应用程序需要尝试发送剩余的数据,(用户需要通过自己)

s.sendall() 发送完整的tcp数据(本质是循环调用send,尝试发送所有数据应用编程接口和套接字,成功则返回none,失败则抛出异常

s.recvfrom() 接收udp数据

s.sendto() 发送udp数据

s.getpeername() 连接到当前socket的远程地址

s.getsocketname() 当前套接字的地址

s.getsockopt() 返回指定socket的参数

s.setsockopt() 设置指定连接的参数

s.close() 关闭套接字

s.fileno() 返回套接字的文件描述符(用于异步编程)

单通讯模式案例

服务器端代码

#!/usr/bin/env  python
import socket
host_info = ("0.0.0.0", 8888)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(host_info)
s.listen()
print("----wait connection-------")
con, addr = s.accept()
con.send("hello, client. we will connection...".encode())
data = con.recv(1024)
print("FROM CLIENT:", data.decode())
con.close()
s.close()

客户端代码

#!/usr/bin/env  python
import socket
c = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
c.connect(("127.0.0.1", 8888))
data = c.recv(1024)
print("from server:", data.decode())
c.send("hello server".encode())
c.close()

交互结果

服务器端结果

客户端结果

一对多互动演示

我刚才演示的是一台服务器对应一台客户端的交互方式,那么一台服务器如何对应多台客户端呢?

服务器端代码

#!/usr/bin/env  python
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(("localhost", 9000))
s.listen(3)
count = 0
while True:
    print("-----wait connetion-----")
    con, addr = s.accept()
    count += 1
    print(f"the {count} conneted,addr is {addr}.")
    while True:
        try:
            data = con.recv(1024)
            con.send(data.decode().upper().encode())
            print(f"from client {addr} data:{data.decode()}")
            if not data:
                break
        except ConnectionResetError as e:
            print(e)
            break

代码解读:

内层while循环是单客户端持续交互的代码,外层while循环是连接多个客户端的代码。

同时处理客户端异常后应用编程接口和套接字,避免服务端抛出异常。

s.listen(3),表示允许排队的客户端数量为3。

客户端代码

#!/usr/bin/env  python
import socket
c = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
    c.connect(("localhost", 9000))
except ConnectionRefusedError as e:
    print(e)
else:
    while True:
        msg = input("client msg>>:").strip()
        if msg == "q":
            break
        try:
            c.send(msg.encode())
            data_from_server = c.recv(1024)
            print("from server msg:", data_from_server.decode())
        except ConnectionResetError as e:
            print(e)
            break

这里处理服务器没有响应的异常ConnectionRefusedError和服务器断开连接的ConnectionResetError。

这是模拟客户端的另一个配置说明。

第一步:

第 2 步:

通过这种方式,可以通过多次执行客户端代码来模拟多个客户端和服务器交互。

服务器

客户端 1

一起来试试吧。如有任何问题,请私信或评论。

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 抢沙发

请登录后发表评论