SocketTCP和UDP编程基础(python)

一、socket_TCP网络通信

Socket 是一种用于实现网络通信的编程接口,它允许不同计算机之间通过网络进行数据交换。在计算机网络编程中,Socket 被广泛应用于客户端-服务器通信和进程间通信等场景。下面是关于 Socket 的一些重要信息:

  1. Socket 是什么

    • Socket 是一种抽象的通信端点,可以用于在不同计算机之间进行数据传输。
    • 在网络编程中,Socket 通常由 IP 地址和端口号组成,用于唯一标识网络中的通信实体。
  2. Socket 的类型

    • 在 Python 中,常用的 Socket 类型有两种:TCP Socket 和 UDP Socket。
    • TCP Socket 提供面向连接的、可靠的数据传输,适用于要求数据完整性的场景。
    • UDP Socket 提供无连接、不可靠的数据传输,适用于要求速度和效率的场景。
  3. Socket 编程

    • 在 Python 中,可以使用内置的 socket 模块进行 Socket 编程。
    • 通过创建 Socket 对象并调用其方法,可以实现网络通信的各种操作,如建立连接、发送数据、接收数据等。
  4. Socket 通信流程

    • 在客户端-服务器通信中,通常的流程是:服务器创建 Socket 并绑定到指定的 IP 地址和端口,然后监听连接;客户端创建 Socket 并连接到服务器指定的 IP 地址和端口;双方建立连接后进行数据交换。
  5. Socket 应用

    • Socket 在网络编程中广泛应用于各种场景,如 Web 服务器、聊天应用、远程控制、文件传输等。
    • 通过 Socket,可以实现不同计算机之间的实时通信和数据交换,为网络应用提供了基础支持。

总的来说,Socket 是一种重要的网络编程接口,通过 Socket 可以实现不同计算机之间的数据传输和通信,为构建各种网络应用提供了基础。在 Python 中,通过内置的 socket 模块,可以方便地进行 Socket 编程。

1.如何实现发信息的网络通信

  1. 硬件接口
  2. 发送信息
  3. 接受信息
  4. 关机

2.通信步骤

  1. 连接
  2. 传输信息
  3. 关闭链接

3.Python实现步骤

服务端实现步骤
  1. 建立服务端Socket对象

    • 使用 socket 模块创建一个服务端的 Socket 对象,指定使用 TCP 协议。
  2. 绑定IP地址和端口号

    • 使用 bind() 方法将服务端的 Socket 对象绑定到指定的IP地址和端口号上。
  3. 设置监听模式

    • 使用 listen() 方法设置 Socket 对象为监听模式,指定最大连接数。
  4. 等待客户端连接

    • 使用 accept() 方法等待客户端的连接请求,一旦有客户端连接,会返回一个新的 Socket 对象和客户端的地址信息。
  5. 接收客户端数据/给客户端发送信息

    • 使用新的 Socket 对象进行数据的接收和发送,可以使用 recv() 方法接收客户端发送的数据,使用 send() 方法发送数据给客户端。
  6. 关闭连接

    • 在通信结束后,关闭服务端的 Socket 对象。
客户端实现步骤
  1. 创建客户端Socket对象

    • 使用 socket 模块创建一个客户端的 Socket 对象,同样指定使用 TCP 协议。
  2. 连接服务端IP和端口

    • 使用 connect() 方法连接到服务端指定的IP地址和端口号。
  3. 接收服务端数据/发送客户端数据

    • 使用客户端 Socket 对象进行数据的接收和发送,可以使用 recv() 方法接收服务端发送的数据,使用 send() 方法发送数据给服务端。
  4. 关闭连接

    • 在通信结束后,关闭客户端的 Socket 对象。
示例代码

下面是一个简单的示例代码,演示了服务端和客户端之间的简单通信过程:

server_socket.py
# 服务端代码

import socket
"""
套接字类:
socket.socket : 这个就是我们的套接字类,里面有两个参数

socket_family : 网络地址类型:ipv4参数值 ==> AF_INET
                            ipv6参数值 ===》 AF_INET6                      
socket_type: 套接字:TCP协议 ==> SOCK_STREAM
                    UDP协议 ==> SOCK_DGRAM

"""
#1.建立服务端对象
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)#表示IPV4地址族通信使用TCP
#2.绑定IP地址和端口号
server_socket.bind(('localhost', 9999))
#3.设置监听数
server_socket.listen(5)#设置监听数为5

print("等待客户端连接...")
"""
accept: 这个方法调用后会有两个返回值
    1.客户端对象(数据),我们以后都要用这个对象进行接受和发送
    2.链接客户端的ip,端口号

"""
#4.等待客户端连接
client_socket, address = server_socket.accept()
print(f"连接来自:{address}")
#5.接收客户端数据/给客户端发送信息
data = client_socket.recv(1024)#1024是设置的最大字节数,单位是b
print(f"收到客户端消息:{data.decode('utf-8')}")

## 数字流转换为文档格式字符串

#给客户端发送信息
client_socket.send("Hello, client!".encode())

# 6.关闭链接

client_socket.close()
server_socket.close()
client_socket.py
# 客户端代码
import socket
#1.创建客户端Socket对象
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#2.连接服务端IP和端口
client_socket.connect(('localhost', 9999))
#3.接收服务端数据/发送客户端数据
client_socket.send("Hello, server!".encode())

# 网络只允许二进制传输,需要encode编译

# encode : 字符串转换为数据流

# decode : 数据流转为字符串

data = client_socket.recv(1024)
print(f"收到服务端消息:{data.decode()}")

client_socket.close()
循环通信
server_socket.py
# 服务端代码
import socket

server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(('localhost', 9999))
server_socket.listen(5)

print("等待客户端连接...")
client_socket, address = server_socket.accept()
print(f"连接来自:{address}")

while 1:
    try:
        data = client_socket.recv(1024)

        print(data.decode("utf-8"))

        msg = input(">>>")
        client_socket.send(msg.encode("utf-8"))

    except ConnectionResetError:
        break

client_socket.close()
server_socket.close()


client_socket.py
import socket

client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(('localhost', 9999))

while 1:
    msg = input(">>>")
    client_socket.send(msg.encode("utf-8"))

    if msg == "再见":
        break

    if not msg:
        continue

    data = client_socket.recv(1024)
    print(data.decode("utf-8"))

client_socket.close()



二、socket_UDP网络通信

服务端:
1.创建服务端socket对象
2.绑定自己的ip和端口号
3.接受客户端数据/发送数据
4.关闭链接

socket --> bind —> recvfrom(收)/sendto(发) —>close

客户端
1.创建客户端socket对象
2.发送数据,接受数据
3.关闭

server.py
import socket

"""
套接字类:
socket.socket : 这个就是我们的套接字类,里面有两个参数

socket_family : 网络地址类型:ipv4参数值 ==> AF_INET
                            ipv6参数值 ===》 AF_INET6 
                            
                            
socket_type: 套接字:TCP协议 ==> SOCK_STREAM
                    UDP协议 ==> SOCK_DGRAM


"""

# 创建套接字对象
# IPhone 就是ipv4,UDP协议的套接字对象
IPhone = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

# 绑定ip和端口号
# 我们的bind参数只有一个实参,这里只能用元组传输
IPhone.bind(("localhost", 10086))


# 5.接受和发送
# 接收数据:设定最大字节数,单位为b
while 1:
    try:
        """
            接受数据:也要最大字节数
            
            recvfrom:这个方法也是有两个返回值
            1.客户端套接字对象
            2.客户端ip和端口号
        
        """

        data, adder = IPhone.recvfrom(1024)

        print(data.decode("utf-8"))

        msg = input(">>>")
        # 发送信息
        IPhone.sendto(msg.encode("utf-8"), adder)

    except ConnectionResetError:
        break


# 6.关闭链接
IPhone.close()



client.py
import socket

# 建立客户端的对象
client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

# 创建一个元组
ipPort = ("127.0.0.1", 10086)

# 网络只允许二进制传输,需要encode编译
# encode : 字符串转换为数据流
# decode : 数据流转为字符串
while 1:
    msg = input(">>>")


    if msg == "拜拜":
        break

    if not msg:
        continue

    client.sendto(msg.encode("utf-8"), ipPort)

    # udp 有一个要求,每一次通讯都要对方的IP地址和端口号
    data, adder = client.recvfrom(1024)
    print(data.decode("utf-8"))

# 4.关闭
client.close()


三、UDP和TCP的比较

1.UDP的优点

  1. 低延迟: UDP是面向无连接的协议,不需要建立连接和维护状态,因此通信过程中的延迟较低。
  2. 高效性: UDP不进行数据重传、流量控制等额外处理,简单高效,适用于实时性要求较高的场景。
  3. 无拥塞控制: UDP不进行拥塞控制,不会因为网络拥塞而调整传输速率,适用于一些特定场景。
  4. 适用于广播和多播: UDP支持广播和多播,可以实现一对多的通信。

2.TCP的优点

  1. 可靠性: TCP提供数据重传、流量控制、拥塞控制等机制,保证数据的可靠传输。
  2. 顺序性: TCP保证数据包按照发送顺序到达接收端,不会出现数据包乱序的情况。
  3. 错误校正: TCP提供校验和机制,可以检测数据传输过程中的错误,保证数据的完整性。
  4. 流量控制: TCP通过滑动窗口机制进行流量控制,避免发送方发送速度过快导致接收方无法处理。

四、socket响应网页(了解)

网页响应数据需要遵守http协议

如果不遵守就无法识别任何响应信息

那么http协议需要你自己编写格式

客户端接受数据:
数据响应格式:
1.响应行(表示http版本 HTTP1.1, 响应状态码)200 表示响应成功
2.响应头(一大堆键值对) 可写可不写
3.\r\n (空白行,每一个响应数据都要用\r\n结束)
4.响应体(需要返回给浏览器看的数据)

1.响应行:HTTP响应报文中的第一行,用于表示服务器对客户端请求的响应状态。响应行通常由三部分组成:HTTP协议版本、状态码和状态码的文本描述。

2.响应头:用于传输关于响应的元数据信息,如服务器类型、日期时间等。

3.响应体包含实际的响应数据,通常是HTML、文本、图片等内容。

请求格式:
1.请求首行(表示http版本,数据请求方法)
2.请求头 可写可不写
3.请求体

静态服务器

server.py
import socket

if __name__ == '__main__':
    tcpServerSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    # 设置端口复用(循环使用),程序退出里面关闭该端口号
    tcpServerSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)

    # "" 这个可以不写,直接空字符,默认是本机地址
    tcpServerSocket.bind(  ("", 8848)  )
    tcpServerSocket.listen(128)

    while 1:
        try:
            newSocket, adder = tcpServerSocket.accept()

            data = newSocket.recv(4096)

            # 打印请求信息
            print(data)

            # 返回一个html前端页面

            with open(r"xyz.html", "r", encoding="utf-8") as f:
                fileData = f.read()


         
            #响应行
            #http/1.1 是http协议版本, 200 ok 是状态码和说明信息
            responseLine = "HTTP/1.0 200 ok \r\n"

            # 响应头
            responseHeader = "server: xyzfuwuqi/1.0 \r\n"

            # 响应体 数据包
            responseBody = fileData

            # 把上面的报文统一组装在一起

            response = responseLine+responseHeader+"\r\n" + responseBody

            # 转化数据流
            responseData = response.encode("utf-8")
            newSocket.send(responseData)
            newSocket.close()
        except Exception as e:
            print(e)
            break



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一只特立独行猪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值