通信知识 Day01

1.网络的概念

网络是指将多个具有独立功能的计算机系统、设备或节点,通过通信线路和通信设备相互连接起来,以实现信息传输、资源共享和协同工作等功能的系统

2.ip地址的介绍

 

3.端口和端口号

 

3.socket介绍

4. TCP介绍,encode,decode

 

Tcp特点:

 

他们之间的关系可以类比为:网络就是社会关系,大家都可以在网络中进行数据传输,但比如说你要和一个人联系,首先你要找到他住的小区,这个小区就是ip地址,光有ip地址还不行,你要找到这个人住的家并且打开门进去说话,这个门就是端口这个门牌号就是端口号,但这就行了吗?你得有路呀,这个路就是scoket,有路就行了吗,你要有交通工具,这个交通工具的一种就是TCP。这样你就可以去联系一个人了哈哈哈。

4.TCP客户端程序开发流程 

import socket

# 创建 TCP 套接字
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 服务器的 IP 地址和端口号
server_address = ('127.0.0.1', 8888)
# 连接服务器
client_socket.connect(server_address)

# 要发送的数据
message = "Hello, Server!"
# 编码并发送数据
client_socket.sendall(message.encode('utf-8'))

# 接收服务器返回的数据
data = client_socket.recv(1024)
# 解码数据
received_message = data.decode('utf-8')
print(f"Received from server: {received_message}")

# 关闭套接字
client_socket.close()

总而言之:

 5.TCP服务端程序开发流程

import socket

# 创建 TCP 套接字
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 服务器的 IP 地址和端口号
server_address = ('127.0.0.1', 8888)
# 绑定地址和端口
server_socket.bind(server_address)

# 开始监听,允许的最大连接队列长度为 5
server_socket.listen(5)
print("Server is listening on port 8888...")

try:
    # 接受客户端连接
    client_socket, client_address = server_socket.accept()
    print(f"Accepted connection from {client_address}")
    try:
        # 接收客户端发送的数据
        data = client_socket.recv(1024)
        # 解码数据
        received_message = data.decode('utf-8')
        print(f"Received from client: {received_message}")

        # 要发送的响应数据
        response = "Hello, Client! Your message has been received."
        # 编码并发送数据
        client_socket.sendall(response.encode('utf-8'))
    finally:
        # 关闭客户端套接字
        client_socket.close()
except KeyboardInterrupt:
    print("Server is shutting down...")
finally:
    # 关闭监听套接字
    server_socket.close()

原理:

6.完整的服务端开发:很明显以上服务器只能一次服务于一个客户端,并且服务端会关闭,接下来是改进方法,首先先让它一直启动着循坏接受请求。 使用While True即可

import socket

if __name__ == '__main__':
    # 1.创建服务端套接字对象
    tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 设置端口复用
    tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
    # 2. 绑定IP地址和端口号
    tcp_server_socket.bind(("", 8888))
    # 3.设置监听 128:代表服务端等待排队连接的最大数量
    tcp_server_socket.listen(128)

    while True:
        # 4. 等待接受客户端的连接请求 accept阻塞等待 返回一个用以和客户端通socket,客户端的地址
        conn_socket, ip_port = tcp_server_socket.accept()
        print("客户端地址:", ip_port)
        try:
            # 5. 接收数据
            recv_data = conn_socket.recv(1024)
            if recv_data:
                print("接收到的数据:", recv_data.decode())
                # 6.发送数据
                conn_socket.send("客户端你的数据我收到了".encode())
            else:
                print(f"客户端 {ip_port} 断开连接")
        except Exception as e:
            print(f"与 {ip_port} 通信出错: {e}")
        finally:
            # 关闭与当前客户端的连接套接字
            conn_socket.close()

    # 关闭监听套接字(正常情况下程序不会执行到这一步,因为在while True循环中)
    tcp_server_socket.close()

这样的话就可以循环接受客户端的连接,但是很明显它们得排队,我们要达到同时的效果,可以采用线程这个方法:

 

import socket
import threading

# 处理客户端请求的函数
def handle_client(conn_socket, client_address):
    try:
        # 接收客户端发送的数据
        recv_data = conn_socket.recv(1024)
        if recv_data:
            try:
                # 尝试将接收到的字节数据解码为字符串
                message = recv_data.decode()
                print(f"接收到来自 {client_address} 的数据:{message}")
                # 向客户端发送响应消息
                conn_socket.send("客户端你的数据我收到了".encode())
            except UnicodeDecodeError:
                print(f"来自 {client_address} 的数据解码失败,可能不是有效的文本数据。")
        else:
            print(f"客户端 {client_address} 主动关闭了连接。")
    except ConnectionResetError:
        print(f"客户端 {client_address} 重置了连接。")
    except OSError as os_err:
        print(f"与客户端 {client_address} 通信时发生 OS 错误: {os_err}")
    except Exception as e:
        print(f"处理客户端 {client_address} 请求时发生未知错误: {e}")
    finally:
        # 无论是否发生异常,最后都关闭与客户端的连接
        conn_socket.close()

if __name__ == "__main__":
    # 创建 TCP 套接字对象,使用 IPv4 地址族和 TCP 协议
    tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 设置套接字选项,允许地址重用,便于程序快速重启
    tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
    # 绑定服务器要监听的 IP 地址和端口号,这里使用空字符串表示监听所有可用的网络接口
    server_address = ('', 8888)
    tcp_server_socket.bind(server_address)
    # 开始监听客户端连接请求,允许的最大连接队列长度为 128
    tcp_server_socket.listen(128)
    print(f"服务器正在监听 {server_address[0]}:{server_address[1]}...")

    try:
        while True:
            # 接受客户端的连接请求,返回用于与客户端通信的新套接字和客户端地址
            conn_socket, client_address = tcp_server_socket.accept()
            print(f"客户端 {client_address} 已连接。")
            # 创建一个新的线程来处理该客户端的请求
            client_thread = threading.Thread(target=handle_client, args=(conn_socket, client_address))
            # 设置线程为守护线程,当主线程退出时,守护线程会自动退出
            client_thread.daemon = True
            # 启动线程
            client_thread.start()
    except KeyboardInterrupt:
        print("服务器接收到手动中断信号,正在关闭...")
    finally:
        # 关闭服务器套接字
        tcp_server_socket.close()

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值