socket的网络编程,快点玩起来吧

什么是 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()被动接受客户的连接,(阻塞式)等待连接的到来

客户端socket函数

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()连接到当前套接字的远端的地址

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

s.getsockopt()返回指定套接字的参数

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

s.close()关闭套接字

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

单一通信模式案例

server端代码

#!/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()

client端代码

#!/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()

交互的结果

一对多交互演示

刚才演示的是一个server对应一个client交互的样式,那么一个server如何对应多个client呢?

server端代码

#!/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个。

client端代码

#!/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。

这里针对模拟客户端多开做一个配置说明。

第一步:

第二步:

如此,多次执行客户端代码就可以模拟多个客户端和服务端交互了。

快点来一起试试吧,有什么问题可以私信或者评论交流哦。

原文链接:,转发请注明来源!