Socket通讯之TCP

Kubrnete
• 阅读 1661

TCP类型客户端

上一篇文章我写到了如何编写UDP类型的通讯,其实TCP类型的通讯本质也是一样的,不过TCP是面向连接的,这里我们就不再过多的介绍有关于协议的一些问题了,毕竟我们是要编写通讯程序,而不是了解协议。

首先我们还是创建一个TCP类型的套接字。

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

因为TCP是面向连接的,而不像UDP是无连接的,所以我们需要连接目标服务器。

# 连接目标服务器
ip_port = (("127.0.0.1"), 1234)
socket_TCP.connect(ip_port)

最后我们就可以完成发送信息了。

 # 发送信息
 socket_TCP.send("Hello World!".encode("gbk"))

这里使用的是gbk编码的,因为在Windows中编码都是gbk,而且我们的网络调试助手,解码也是gbk所以按照上一篇文字的utf-8进行编码的话就会出现乱码现象。

然后我们运行这个代码就可以在我们的网络调试助手里看到我们发送的信息了。

Socket通讯之TCP 那么我们将上面的片段整理在一起就是这个样子。

# 创建套接字
socket_TCP = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 连接目标服务器
ip_port = (("127.0.0.1"), 1234)
socket_TCP.connect(ip_port)
# 发送信息
socket_TCP.send("Hello World!".encode("gbk"))

最后我们的客户端也就编写完成了,我们也可以优化一下,让发送的信息可控化,输入exit就可以退出发送信息。

# 创建套接字
socket_TCP = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 连接目标服务器
ip_port = (("127.0.0.1"), 1234)
socket_TCP.connect(ip_port)
while True:
    # 发送信息
    data = input("请输入你要发送的信息:")
    socket_TCP.send(data.encode("gbk"))
    if data == "exit":
        socket_TCP.close()
        break

运行: Socket通讯之TCP

TCP类型服务端

我们需要想想我们编写一个服务端需要经过那几个步骤。

  1. 创建一个TCP的套接字
  2. 绑定本地IP及其端口
  3. 设置允许连接的个数
  4. 等待连接,从而产生一个新的套接字服务于通讯
  5. 接收来自客户端的信息

在这里是与UDP有些不同了,多了一个允许连接的次数,还有一个等待连接的操作。

第一步,创建套接字

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

第二步,绑定IP及其端口信息

# 绑定IP及其端口
ip_port = (("127.0.0.1"), 1234)
socket_TCP.bind(ip_port)

第三步,设置允许同时连接的个数(这里我们默认128即可)

# 设置允许接入的连接数
socket_TCP.listen(128)

第四步,等待连接,从而产生一个新的套接字服务于通讯

"""创建一个新的套接字用于一个新的通讯"""
socket_new_TCP, Adress = socket_TCP.accept()

第五步,接收来自客户端的信息

# 接收来自客户端的信息
socket_new_data = socket_new_TCP.recv(1024).decode("utf-8")
print(socket_new_data)

这里我们可以发现第四步,多了一个新的套接字和一个地址,我们将地址打印出来看看。

('127.0.0.1', 63011)

发现里面是一个元祖,里面存储了ip信息及其端口信息,我们可以将它提取出来。

# IP信息
ip = Address[0]
# 端口信息
port = Address[1]
# 接收来自客户端的信息
socket_new_data = socket_new_TCP.recv(1024).decode("utf-8")
print("[*] 来自 %s:%s 的信息:%s" % (ip, port, socket_new_data))

最后我们整合代码运行一下,可以很容易的看到来自客户端的信息。

[*] 来自 127.0.0.1:63052 的信息:Hello World

完整代码如下:

# 创建套接字
socket_TCP = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 绑定IP及其端口
ip_port = (("127.0.0.1"), 1234)
socket_TCP.bind(ip_port)
# 设置允许接入的连接数
socket_TCP.listen(128)
"""创建一个新的套接字用于一个新的通讯"""
socket_new_TCP, Address = socket_TCP.accept()
# IP信息
ip = Address[0]
# 端口信息
port = Address[1]
# 接收来自客户端的信息
socket_new_data = socket_new_TCP.recv(1024).decode("utf-8")
print("[*] 来自 %s:%s 的信息:%s" % (ip, port, socket_new_data))

我们也可以让他循环接收,这里我还相对优化了一下。

# 创建套接字
socket_TCP = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 绑定IP及其端口
ip_port = (("127.0.0.1"), 1234)
socket_TCP.bind(ip_port)
# 设置允许接入的连接数
socket_TCP.listen(128)
"""创建一个新的套接字用于一个新的通讯"""
socket_new_TCP, Address = socket_TCP.accept()
while True:
    # IP信息
    ip = Address[0]
    # 端口信息
    port = Address[1]
    # 接收来自客户端的信息
    socket_new_data = socket_new_TCP.recv(1024).decode("utf-8")
    print("[*] 来自 %s:%s 的信息:%s" % (ip, port, socket_new_data))
    if socket_new_data == "exit":
        socket_new_TCP.close()
        socket_TCP.close()
        break

我们运行后可以看到如下信息:

[*] 来自 127.0.0.1:63069 的信息:Hello
[*] 来自 127.0.0.1:63069 的信息:你好
[*] 来自 127.0.0.1:63069 的信息:!!!
[*] 来自 127.0.0.1:63069 的信息:exit

功能集合

接下来我们将发送信息和接收信息整合在一起来看看。

import socket


def main():
    print("请选择功能:\n"
          "1. 发送数据\n"
          "2. 接收数据\n"
          "3. 退出程序")
    while True:
        choose = int(input("请输入你的选择:"))
        # 调用函数
        if choose == 1:
            Send()
        elif choose == 2:
            Rece()
        elif choose == 3:
            exit()
        else:
            print("输入有误请重新输入!")


def Send():
    # 创建套接字
    socket_TCP = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 连接目标服务器
    ip_port = (("127.0.0.1"), 1234)
    socket_TCP.connect(ip_port)
    while True:
        # 发送信息
        data = input("请输入你要发送的信息:")
        socket_TCP.send(data.encode("utf-8"))
        if data == "exit":
            socket_TCP.close()
            break


def Rece():
    # 创建套接字
    socket_TCP = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 绑定IP及其端口信息
    ip_port = (("127.0.0.1"), 1234)
    socket_TCP.bind(ip_port)
    # 设置允许连接的个数
    socket_TCP.listen(128)
    """等待连接生成一个新的套接字服务于通讯"""
    socket_new_TCP, Address = socket_TCP.accept()
    while True:
        # 接收信息
        socket_new_data = socket_new_TCP.recv(1024).decode("utf-8")
        # IP信息
        ip = Address[0]
        # 端口信息
        port = Address[1]
        print("[*] 来自 %s:%s 的信息为:%s" % (ip, port, socket_new_data))
        if socket_new_data == "exit":
            socket_new_TCP.close()
            socket_TCP.close()
            break


if __name__ == '__main__':
    main()

运行:

客户端:

请选择功能:
1. 发送数据
2. 接收数据
3. 退出程序
请输入你的选择:1
请输入你要发送的信息:你好!
请输入你要发送的信息:Hello World!
请输入你要发送的信息:exit
请输入你的选择:3

服务器:

请选择功能:
1. 发送数据
2. 接收数据
3. 退出程序
请输入你的选择:2
[*] 来自 127.0.0.1:63163 的信息:你好!
[*] 来自 127.0.0.1:63163 的信息:Hello World!
[*] 来自 127.0.0.1:63163 的信息:exit
请输入你的选择:3
点赞
收藏
评论区
推荐文章

暂无数据