首页 > 其他分享 >socket

socket

时间:2024-01-14 20:57:49浏览次数:21  
标签:socket AF print message INET 客户端

引入

Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。

所以,我们无需深入理解tcp/udp协议,socket已经为我们封装好了,我们只需要遵循socket的规定去编程,写出的程序自然就是遵循tcp/udp标准的。

AF_UNIX

基于文件类型的套接字家族

在unix中,一切皆文件,基于文件的套接字调用的就是底层的文件系统来获取数据
两个套接字进程运行在同一机器,可以通过访问同一个文件系统间接完成通信

AF_INET

基于网络类型的套接字家族

AF_INET是使用最广泛的一个,python支持很多种地址家族,但是由于我们只关心网络编程,故大多只使用AF_INET。

socket模块

基于网络类型的套接字,应用程序交流按照链接的有无,又分为基于tcp的套接字和基于udp的套接字

python中的socket模块帮我们封装了socket抽象层,并提供我们一些简单接口使用。

建立TCP连接

注意事项1:发送请求应该是由客户端向服务端主动发送,服务端不会主动向客户端发送

注意事项2:关闭连接服务器以及客户端都是可以主动关闭的,但是通常情况下应该由客户端去关闭,而不是服务端,除非客户端疯狂请求之类。

# 服务端
import socket


# 创建一个TCP socket     # AF_INET代表ipv4家族   SOCK_STREAM代表TCP协议
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# IP地址和端口号, 端口号别给0-1024之间  IP地址如果是0.0.0.0 表主机的任意网卡都可以使用socket通信
server_address = ("127.0.0.1", 8080)
# 绑定地址和端口
server_socket.bind(server_address)
# 将socket设置为监听状态,并等待客户端链接,默认值为 socket.SOMAXCONN。
# socket.SOMAXCONN 是一个系统定义的常量,表示操作系统允许的最大连接数。
server_socket.listen()
print("链接已创建 等待客户端链接...")
try:
    # 使用 accept() 方法接受客户端的连接,返回一个新的 Socket 对象和客户端地址。
    client_socket, client_address = server_socket.accept()
    print(f"客户端 [{client_address}] 已成功连接! ")
    # 和客户端通信 这里要用客户端去回信 不然会报错 记得消息是二进制的
    data = client_socket.recv(1024).decode()
    print(f"来自客户端的消息:{data}")
    client_socket.send("客户端 你好 ^_^".encode())
finally:
    # 依次关闭客户端和服务端
    client_socket.close()
    server_socket.close()
# 客户端 
import socket

 
# 创建socket  # AF_INET代表ipv4家族   SOCK_STREAM代表TCP协议
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 服务器的地址和端口
server_address = ("127.0.0.1", 8080)
try:
    # 链接服务器
    client_socket.connect(server_address)
    # 给服务器发送数据 注意要编码
    message = "服务器 你好!"
    client_socket.send(message.encode()) # 这里如果不指定编码格式 默认就是utf-8
    # 接收服务器响应
    response = client_socket.recv(1024) # 单位是字节
    print(f"来自服务器的消息:{response.decode()}")
except socket.error as e:
    print(f"发生了错误: {e}")
finally:
    client_socket.close()

image-20240112193930059

优化纯享版

因为使用了上下文管理器所以不需要手动关闭服务了

# 服务端
import socket

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.bind(("127.0.0.1", 8080))
    s.listen()
    print("链接已创建 等待客户端链接...")
    c, addr = s.accept()
    with c:
        data = c.recv(1024).decode()
        print(f"来自客户端的消息:{data}")
        c.send("客户端 你好 ^_^".encode())
# 客户端
import socket

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as c:
    c.connect(("127.0.0.1", 8080))
    message = "服务器 你好!"
    c.send(message.encode())
    response = c.recv(1024).decode()
    print(f"来自服务器的消息:{response}")

如何循环发送消息

加一个循环不就好了...

# 服务端
import socket

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.bind(("127.0.0.1", 8080))
    s.listen()
    print("链接已创建 等待客户端链接...")
    c, addr = s.accept()
    with c:
        while (data := c.recv(1024)):
            print(f"来自客户端的消息:{data.decode()}")
            message = input("输入需要发送给客户端的消息:")
            c.send(message.encode())
        else:
            print("系统提示:客户端已下线,链接已关闭...")
# 客户端
import socket

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as c:
    c.connect(("127.0.0.1", 8080))
    while True:
        message = input("输入需要发送给服务器的消息:")
        if len(message) < 1:
            print("您已主动已关闭连接")
            break
        c.send(message.encode())
        response = c.recv(1024).decode()
        print(f"来自服务器的消息:{response}")

image-20240112203313356

问题

没有捕获异常 很容易让程序卡死,建议捕获异常。

# 服务端
import socket

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.bind(("127.0.0.1", 8080))
    s.listen()
    print("链接已创建 等待客户端链接...")
    
    while 1:
        try:
            c, addr = s.accept()
            while (data := c.recv(1024)):
                print(f"来自客户端{addr}的消息:{data.decode()}")
                message = input("输入需要发送给客户端的消息:")
                c.send(message.encode())
            else:
                print("系统提示:客户端已下线,链接已关闭...")
                break
                c.close()
        except socket.error as e:
            print(e)
            break
# 客户端
import socket

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as c:
    c.connect(("127.0.0.1", 8080))
    while True:
        try:
            message = input("输入需要发送给服务器的消息:")
            if len(message) < 1:
                print("您已主动已关闭连接")
                break
            c.send(message.encode())
            response = c.recv(1024).decode()
            print(f"来自服务器的消息:{response}")
        except ConnectionResetError:
            print("服务端主动下线,连接已关闭.")
            break

UDP方式发送

# server.py
import socket

# 创建UDP socket
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
    # 绑定IP地址和端口号
    s.bind(("127.0.0.1", 8080))
    
    # 接收数据和客户端地址
    data, addr = s.recvfrom(1024)
    
    # 打印客户端地址和接收到的数据(解码)
    print("Client Address:", addr)
    print("Received Data:", data.decode())

# client.py
import socket

# 创建UDP socket
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as c:
    # 服务器地址
    server_address = ("127.0.0.1", 8080)
    
    # 发送数据到服务器
    c.sendto("你好,我是UDP".encode(), server_address)

标签:socket,AF,print,message,INET,客户端
From: https://www.cnblogs.com/ccsvip/p/17964167

相关文章

  • boost框架 创建websocket非阻塞服务
    #include<iostream>#include<boost/asio.hpp>#include<boost/beast.hpp>#include<boost/beast/websocket.hpp>namespaceasio=boost::asio;namespacebeast=boost::beast;namespacewebsocket=beast::websocket;usingtcp=asio::......
  • WebSocket-FLV H264/H265服务器基本实现
    场景HTTP-FLV:基于HTTP流式IO传输FLV,依赖浏览器支持播放FLV。但是由于同源的限制问题,浏览器只能播放六路视频,因此采用WebSocket-FLVWebSocket-FLV:基于WebSocket传输FLV,依赖浏览器支持播放FLV。WebSocket建立在HTTP之上,建立WebSocket连接前还要先建立HTTP连接。视频参数代码H264S......
  • python socket服务端
    pythonsocket服务端importsocket#创建socket对象server_socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)#绑定IP地址和端口号server_socket.bind(('127.0.0.1',8000))#监听连接server_socket.listen(1)print('等待客户端连接...')whileTru......
  • socket编程 [补档-2023-07-10]
    Linux网络编程1.socket编程socket是一种通信机制,用于在网络中不同计算机之间进行数据传输,当然也可用用于进程间通信。在linux中,有文件描述符这么个东西,我们可以通过socket函数创建一个网络连接,socket的返回值为一个文件描述符,我们拿到这个文件描述符就可以像操作普通io文件那样......
  • Winform中使用Fleck实现Websocket服务端并读取SQLite数据库中数据定时循环群发消息
    场景Winform中使用Websocket4Net实现Websocket客户端并定时存储接收数据到SQLite中:Winform中使用Websocket4Net实现Websocket客户端并定时存储接收数据到SQLite中-Winform中操作Sqlite数据增删改查、程序启动时执行创建表初始化操作:Winform中操作Sqlite数据增删改查、程序启动时执......
  • Winform中使用Websocket4Net实现Websocket客户端并定时存储接收数据到SQLite中
    场景SpringBoot+Vue整合WebSocket实现前后端消息推送:SpringBoot+Vue整合WebSocket实现前后端消息推送_websocketvue3.0springboot往客户端推送上面实现ws推送数据流程后,需要在windows上使用ws客户端定时记录收到的数据到文件中,这里文件使用SQLite数据库进行存储。Winform中操作S......
  • http和websocket的一些思考
    InCivetWeb,thetermsCivetHandlerandCivetWebSocketHandlerarerelatedtodifferenttypesofrequesthandling.CivetHandler:CivetHandlerisagenericclassinCivetWebthatisusedforhandlingHTTPrequests.Whenyoucreateaclassthatinheritsfr......
  • WebSocket与JavaScript:实现实时地理位置定位系统的关键技术
    Laravel是一个流行的PHP框架,它具有出色的可测试性,可以帮助开发人员在更短的时间内编写可靠的代码。但是,即使使用了这个框架,也可能会出现测试覆盖率较低的情况。测试覆盖率是指代码中已由测试案例覆盖的部分比例。测试覆盖率越高,代码质量越高。在本文中,我们将分享几种技巧,帮助您提......
  • 如何使用WebSocket和JavaScript实现在线人脸识别系统
    Laravel是一个流行的PHP框架,它具有出色的可测试性,可以帮助开发人员在更短的时间内编写可靠的代码。但是,即使使用了这个框架,也可能会出现测试覆盖率较低的情况。测试覆盖率是指代码中已由测试案例覆盖的部分比例。测试覆盖率越高,代码质量越高。在本文中,我们将分享几种技巧,帮助您提......
  • SpringBoot WebSocket 样例
    SpringBootWebSocket样例pom.xml依赖配置<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency><dependency><groupId>javax.webso......