Socket模块(网络编程)

junlan
8
2024-11-25

一、Socket(TCP协议)

1. 一次性收发信息的工具

Server端配置:

import socket  # 内置模块,无需安装

sk = socket.socket()   # 实例化一个socket对象
sk.bind(('127.0.0.1', 8080))  # 绑定IP地址和端口号
sk.listen()  # 开始监听

conn, addr = sk.accept()  # 等待连接请求(只接受一次请求),会返回连接和客户端的IP地址

conn.send(b'Hello, client!')  # 连接成功发送(butes类型)内容

msg = conn.recv(1024)   # 一次性接受1024个字节
print(msg.decode('utf-8'))  # Client发送的是utf-8编码的内容,接受也需要使用同样的编码

conn.close()  # 关掉连接
sk.close()    # 关掉socket

Client端配置:

import socket

sk = socket.socket()

sk.connect(("127.0.0.1", 8080))  # 指定Server端的地址,和bind()方式制定的ip和端口号要对应

print(sk.recv(1024).decode())

sk.send('你好,世界!'.encode('utf-8'))

sk.close()

2. 实现简单的聊天工具

Server端代码:

import socket

sk = socket.socket()
sk.bind(('127.0.0.1', 8080))
sk.listen()

conn, addr = sk.accept()
print('Connected succeed by', addr)

while True:
    # 由Server端发起聊天内容
    msg_send = input('>>>')
    conn.send(msg_send.encode('utf-8'))
    if msg_send.upper() == 'Q':
        print('Exit the program!')
        break
    # 接受Client端的内容
    msg_recv = conn.recv(1024).decode('utf-8')
    print(msg_recv)
    if msg_recv.upper() == 'Q': break

conn.close()
sk.close()

Client 代码:

import socket

sk = socket.socket()

sk.connect(("127.0.0.1", 8080))

while True:

    msg_recv = sk.recv(1024).decode('utf-8')
    print(msg_recv)
    if msg_recv.upper() == 'Q':
        print('Server has exited the chat!')
        break

    msg_send = input('>>>')
    if msg_send.upper() == 'Q':
        print('Exit the chat!')
        break
    sk.send(msg_send.encode('utf-8'))

sk.close()

二、解决TCP协议黏包问题

Server端代码:

import socket
import struct

def my_send(conn, msg):
    msg_bytes =msg.encode('utf-8')
    len_msg=len(msg_bytes)
    pack_len=struct.pack('i',len_msg)
    conn.send(pack_len)
    conn.send(msg_bytes)

sk = socket . socket ( )
sk.bind(('127.0.0.1',60000))
sk.listen ( )
conn, addr = sk.accept()
msg1 ='你好'
msg2 =' 吃了么'
my_send(conn,msg1)
my_send(conn,msg2)
conn.close()
sk.close()

Client端代码:

import socket
import struct

sk = socket.socket()
def my_recv(sk):
    pack_len = sk.recv(4)
    len_msg=struct.unpack('i',pack_len)[0]
    msg = sk.recv(len_msg).decode('utf-8')
    return msg

sk.connect(('127.0.0.1',60000))
# for i in range(100000):i*2
msg = my_recv(sk)
print(msg)
msg = my_recv(sk)
print(msg)
sk.close()

三、Socket(UDP协议)

Server端代码:

import socket

sk = socket.socket(type = socket.SOCK_DGRAM)  # create a UDP socket, SOCK_DGRAM means UDP
sk.bind(('127.0.0.1', 8080))

# receive message from client
msg,addr = sk.recvfrom(1024)
print(msg.decode('utf-8'),addr)

# send message to client
send_msg = 'Hello, I am server!'
sk.sendto(send_msg.encode('utf-8'), addr)

sk.close()

Client端代码:

import socket

sk = socket.socket(type = socket.SOCK_DGRAM)

# send the message
send_msg = 'Hello, World!'
sk.sendto(send_msg.encode('utf-8'), ('127.0.0.1', 8080))

# receive the message
msg, addr = sk.recvfrom(1024)
print(msg.decode('utf-8'))
sk.close()