TCP/IP Sockets

268 阅读2分钟

特殊地址

Lookback address:127.0.0.1(IPv4);0.0.0.0.0.0.0.1 (IPv6)

client

典型的TCP客户的通信涉及如下4个基本步骤。

  1. 使用socket()创建TCP套接字。
  2. 使用connect()建立到达服务器的连接。
  3. 使用send()和recv()通信。
  4. 使用close()关闭连接。

server

服务器的职责是建立通信端点,并被动等待来自客户的连接。对于基本的TCP服务器通信,要执行如下4个常规的步骤。

  1. 使用socket()创建TCP套接字。
  2. 利用bind()给套接字分配端口号。
  3. 使用listen()告诉系统允许对该端口建立连接。
  4. 反复执行一下操作:
    • 调用accept()为每个客户连接获取新的套接字。
    • 使用send()和recv()通过新的套接字与客户通信。
    • 使用close()关闭客户连接。

代码


# client.py
import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((socket.gethostname(), 1234))
print(socket.gethostname())

msg = s.recv(1024)
print(msg.decode("utf-8"))
# server.py
import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((socket.gethostname(), 1234))
s.listen(5)

while True:
    clientsocket, address = s.accept()
    print(f"Connection from {address} has been established!")
    clientsocket.send(bytes("Welcome to the server!", "utf-8"))
    clientsocket.close()


# server.py
import socket
import time

HEADERSIZE = 10


s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((socket.gethostname(), 1234))
s.listen(5)

while True:
    # 端到端连接
    clientsocket, address = s.accept()
    print(f"Connection from {address} has been established!")

    msg = 'Welcome to the server!'
    msg = f'{len(msg):<{HEADERSIZE}}' + msg

    clientsocket.send(bytes(msg, 'utf-8'))
    
    while True:
        time.sleep(2)
        msg = f'The time is {time.ctime}'
        msg = f'{len(msg):<{HEADERSIZE}}' + msg

        print(msg)

    clientsocket.close()
# client.py
import socket

HEADERSIZE = 10 

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((socket.gethostname(), 1234))

while True:
    full_msg = ''
    new_msg =True
    while True:
        msg = s.recv(16)
        if new_msg:
            print('new msg len:',msg[:HEADERSIZE])
            msglen = int(msg[HEADERSIZE])
            new_msg = False

        print(f'full message length: {msglen}')

        full_msg += msg.decode('utf-8')
        print(len(full_msg))

        if len(full_msg)-HEADERSIZE == msglen:
            print('full msg recvd')
            print(full_msg[HEADERSIZE:])
            new_msg = True
            full_msg = ""



sockets 服务器与客户端之间传递消息,消息的格式需要是bytes形式,pickle模块则可以将文本形式转换成bytes形式。

import socket
import time
import pickle


HEADERSIZE = 10

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((socket.gethostname(), 1243))
s.listen(5)

while True:
    # now our endpoint knows about the OTHER endpoint.
    clientsocket, address = s.accept()
    print(f"Connection from {address} has been established.")

    d = {1:"hi", 2: "there"}
    msg = pickle.dumps(d)
    msg = bytes(f"{len(msg):<{HEADERSIZE}}", 'utf-8')+msg
    print(msg)
    clientsocket.send(msg)
import socket
import pickle

HEADERSIZE = 10

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((socket.gethostname(), 1243))

while True:
    full_msg = b''
    new_msg = True
    while True:
        msg = s.recv(16)
        if new_msg:
            print("new msg len:",msg[:HEADERSIZE])
            msglen = int(msg[:HEADERSIZE])
            new_msg = False

        print(f"full message length: {msglen}")

        full_msg += msg

        print(len(full_msg))

        if len(full_msg)-HEADERSIZE == msglen:
            print("full msg recvd")
            print(full_msg[HEADERSIZE:])
            print(pickle.loads(full_msg[HEADERSIZE:]))
            new_msg = True
            full_msg = b""