网络编程之基于TCP协议的socket套接字编程

基于TCP的套接字

【1】方法简介

  • tcp是基于链接的
    • 必须先启动服务端
    • 然后再启动客户端去链接服务端
  • tcp服务端
server = socket() #创建服务器套接字
server.bind()      #把地址绑定到套接字
server.listen()      #监听链接
inf_loop:      #服务器无限循环
    conn = server.accept() #接受客户端链接
    comm_loop:         #通讯循环
        conn.recv()/conn.send() #对话(接收与发送)
    conn.close()    #关闭客户端套接字
server.close()        #关闭服务器套接字(可选)
  • tcp客户端
client = socket()    # 创建客户套接字
client.connect()    # 尝试连接服务器
comm_loop:        # 通讯循环
    client.send()/client.recv()    # 对话(发送/接收)
client.close()            # 关闭客户套接字

【2】打电话模型

【1.0】基础版

  • 服务端
# 先写服务端
# 打电话

import socket

# 【1】先有电话
server = socket.socket()

# 【2】电话要插卡
# ('ip','port')
IP = '127.0.0.1'  # 本地的回环地址 / localhost
PORT = 8080
server.bind((IP, PORT))

# 【3】可能会接受到别人的电话
# 半连接池 :
server.listen(5)

# 【4】接电话
conn, addr = server.accept()
# print(f'conn :>>>> {conn}')
# print(f'addr :>>>> {addr}')
# # conn :>>>> <socket.socket fd=352, family=2, type=1, proto=0, laddr=('127.0.0.1', 8080), raddr=('127.0.0.1', 50851)>
# # addr :>>>> ('127.0.0.1', 50851)

# 【5】接受消息
# 参数 : 接收到的数据的大小
from_to_client_msg = conn.recv(1024)
from_to_client_msg = from_to_client_msg.decode('utf-8')
print(f'from_to_client_msg :>>>> {from_to_client_msg}')

# 【6】回复消息
# 传输的数据是二进制格式的数据
# send_msg = b'你好'
send_to_client_msg = '你好'
send_to_client_msg = send_to_client_msg.encode('utf-8')
conn.send(send_to_client_msg)

# 【7】挂断电话
conn.close()

# 【8】手机关机
server.close()
  • 客户端
import socket

# 【1】有一部手机
client = socket.socket()

# 【2】接电话,知道别人的电话号
IP = '127.0.0.1'
PORT = 8080
client.connect((IP, PORT))

# 【3】发送消息
send_to_server_msg = f'我是客户端'
send_to_server_msg = send_to_server_msg.encode('utf-8')
client.send(send_to_server_msg)

# 【4】接受消息
from_server_msg = client.recv(1024)
# 二进制数据解码
from_server_msg = from_server_msg.decode('utf-8')
print(f'from_server_msg :>>>> {from_server_msg}')

# 【5】挂电话
client.close()

基础版模版

############ 服务端
# 导入模块
from socket import socket

# 创建socket对象
server = socket()
# 监听端口
IP = '127.0.0.1'
PORT = 9080
server.bind((IP, PORT))
# 监听连接对象个数
server.listen(5)
# 创建连接对象
conn, addr = server.accept()
# 通过连接对象接收数据 1kb = 1024 bytes
from_client_lsg = conn.recv(1024)
from_client_lsg = from_client_lsg.decode('utf8')
print(from_client_lsg)
# 回数据
send_to_client_msg = '我是服务端'
send_to_client_msg = send_to_client_msg.encode('utf8')
conn.send(send_to_client_msg)
# 关闭链接
conn.close()
# 关闭连接
server.close()

############ 客户端
from socket import socket
# 创建客户端对象
client = socket()
# 监听连接
# 监听端口
IP = '127.0.0.1'
PORT = 9080
client.connect((IP, PORT))
# 发送
send_to_server_msg = '我是客户端'
send_to_server_msg = send_to_server_msg.encode('utf8')
client.send(send_to_server_msg)
# 接收
from_server_msg = client.recv(1024)
from_server_msg = from_server_msg.decode('utf8')
print(from_server_msg)
# 关闭链接
client.close()

【2.0】循环版

  • server
# 先写服务端
# 打电话

import socket

# 【1】先有电话
server = socket.socket()

# 【2】电话要插卡
# ('ip','port')
IP = '127.0.0.1'  # 本地的回环地址 / localhost
PORT = 8060
server.bind((IP, PORT))

# 【3】可能会接受到别人的电话
# 半连接池 :
server.listen(5) # 限制客户端数量

while True:
    # 【4】接电话
    conn, addr = server.accept()

    # 【5】接受消息
    from_to_client_msg = conn.recv(1024)
    from_to_client_msg = from_to_client_msg.decode('utf-8')
    print(f'from_to_client_msg :>>>> {from_to_client_msg}')

    # 【6】回复消息
    # 传输的数据是二进制格式的数据
    # send_msg = b'你好'
    while True:
        send_to_client_msg = input("请输入需要发送的消息 :>>>> ").strip()
        if not send_to_client_msg:
            print(f'当前不能为空!请重新输入!')
            continue
        send_to_client_msg = send_to_client_msg.encode('utf-8')
        conn.send(send_to_client_msg)
        break
# 【7】挂断电话
conn.close()

# 【8】手机关机
server.close()
  • client
import socket

while True:
    # 【1】有一部手机
    client = socket.socket()

    # 【2】接电话,知道别人的电话号
    IP = '127.0.0.1'
    PORT = 8060
    client.connect((IP, PORT))
    # 【3】发送消息 --- 发送的消息不能为空
    send_to_server_msg = input("请输入发送的消息 :>>>> ").strip()
    if not send_to_server_msg:
        print(f'当前不能为空!请重新输入!')
        continue
    send_to_server_msg = send_to_server_msg.encode('utf-8')
    client.send(send_to_server_msg)

    # 【4】接受消息
    from_server_msg = client.recv(1024)
    # 二进制数据解码
    from_server_msg = from_server_msg.decode('utf-8')
    print(f'from_server_msg :>>>> {from_server_msg}')

    # 【5】挂电话
client.close()

循环版模版

############ 客户端
# 创建对象
from socket import socket

while True:
    client = socket()

    # 创键连接
    client.connect(('127.0.0.1', 9696))

    # 发送消息
    send_msg = input("请输入消息 :>>>> ").strip()
    if not send_msg: continue
    client.send(send_msg.encode('utf-8'))
    if send_msg == 'q':
        client.close()
        break
    # 接收消息
    msg = client.recv(1024)
    print(msg.decode('utf8'))

############ 服务端
from socket import socket

server = socket()

server.bind(('127.0.0.1', 9696))

server.listen(5)

while True:
    conn, addr = server.accept()
    # 先接受
    msg = conn.recv(1024)
    msg = msg.decode('utf8')
    print(f'msg:>>>{msg}')
    if msg == 'q':
        conn.close()
        break
    # 再发送
    while True:
        send_msg = input("发送的消息 :>>>> ").strip()
        if not send_msg: continue
        conn.send(send_msg.encode('utf8'))
        break
server.close()

空数据的处理

  • TCP协议是水流式协议:传入的数据不能为空,因为水是一直流的,在传输过程中不会对数据进行操作
  • UDP协议是数据报协议:传入的数据可为空,在传输过程中UDP会对数据进行内部的拼接和处理

断开链接的影响

  • TCP协议是水流式协议:在建立链接过程中,服务端和客户端的链接是一直存在的,断开一方都会对另一方造成影响
  • UDP协议是数据报协议:在建立链接过程中,是通过解析对方数据中的ip和端口,再向另一方返回数据的,所以一方发生问题并不会影响到另一方
posted @ 2024-01-16 21:00  Xiao0101  阅读(28)  评论(0)    收藏  举报