TCP客户端

tcp的客户端要比服务器端简单很多,tcp和服务端建立连接后,直接发送数据
TCP客户端%26服务端 - 图1

开发步骤

  1. 导入socket模块
  2. 创建socket套接字
  3. 建立tcp连接(和服务端建立连接)
  4. 开始发送数据(到服务端)
  5. 关闭套接字

    参考代码

    TCP客户端发送数据

    1. # 1、导入socket模块
    2. import socket
    3. # 2、创建socket
    4. tcp_client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    5. # 3、建立tcp连接
    6. tcp_client_socket.connect(("192.168.23.247", 7878))
    7. # 4、开始发送数据
    8. tcp_client_socket.send("哈哈哈,打不过我吧!?".encode())
    9. # 5、关闭套接字
    10. tcp_client_socket.close()

    TCP客户端发送并接收数据

    ```python

    1、导入socket模块

    import socket

    2、创建socket

    tcp_client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    3、建立tcp连接

    tcp_client_socket.connect((“192.168.23.247”, 7878))

    4、开始发送数据

    tcp_client_socket.send(“哈哈哈,打不过我吧!?”.encode())

开始接收对方回复的数据

recv_data = tcp_client_socket.recv(1024) print(“接收到数据:”, recv_data.decode())

5、关闭套接字

tcp_client_socket.close()

  1. <a name="yA9sA"></a>
  2. ### 关键方法回顾
  3. - `socket.socket(socket.AF_INET, socket.SOCK_STREAM)`
  4. 创建socket套接字对象,`socket.AF_INET`代表IPv4,`socket.SOCK_STREAM`TCP数据流
  5. - `socket.connect(address)`
  6. 主动初始化TCP服务器连接,一般address的格式为元组(hostname, port),如果连接出错,返回socket.error错误。
  7. - `socket.send(要发送的数据)`
  8. 向服务端发送数据,此处的数据必须是二进制类型(字符串则需要编码)
  9. - `socket.recv(缓冲区大小)`
  10. 接收TCP数据,数据以二进制形式返回,bufsize指定要每次接收的最大数据量。
  11. <a name="PbMoP"></a>
  12. ## TCP服务端
  13. tcp服务器:和客户端建立连接后,接收/发送数据给客户端<br />![](https://cdn.nlark.com/yuque/0/2023/png/27903758/1685090894298-51d2d812-6fef-47b8-aa97-6f5a892e54e7.png#averageHue=%2381d353&clientId=u26139ad1-5aef-4&from=paste&id=ud8e924b3&originHeight=976&originWidth=1716&originalType=url&ratio=1&rotation=0&showTitle=false&status=done&style=none&taskId=u7c10c755-d1ae-406c-84d2-45c02844846&title=)
  14. <a name="SvQdf"></a>
  15. ### 开发步骤
  16. 1. `socket`创建一个套接字
  17. 2. `bind`绑定ip和port
  18. 3. `listen`使套接字设置为被动模式
  19. 4. `accept`等待客户端的链接
  20. 5. `recv`/`send`接收发送数据
  21. <a name="gGjGP"></a>
  22. ### 参考代码
  23. <a name="e6Fan"></a>
  24. #### 接收客户端消息并回复
  25. ```python
  26. from socket import *
  27. # 创建socket
  28. tcp_server_socket = socket(AF_INET, SOCK_STREAM)
  29. # 服务IP和端口
  30. address = ('', 7788)
  31. # 绑定服务器IP和端口
  32. tcp_server_socket.bind(address)
  33. # 使用socket创建的套接字默认的属性是主动的,使用listen将其变为被动的,
  34. # 参数128表示:允许同时排队等待连接的最大连接数为128
  35. tcp_server_socket.listen(128)
  36. # 如果有新的客户端来链接服务器,那么就产生一个新的套接字专门为这个客户端服务
  37. # client_socket用来为这个客户端服务
  38. # tcp_server_socket就可以省下来专门等待其他新客户端的链接
  39. client_socket, ip_port = tcp_server_socket.accept()
  40. print("已经连接客户端:", ip_port)
  41. # 接收对方发送过来的数据
  42. recv_data = client_socket.recv(1024) # 接收1024个字节
  43. print('收到数据:%s' % recv_data.decode('gbk'))
  44. # 发送一些数据到客户端
  45. client_socket.send("好的,已经收到!~".encode('gbk'))
  46. # 关闭为这个客户端服务的套接字,只要关闭了,就不能再为这个客户端服务了
  47. # 如果还需要服务,只能再次重新连接
  48. client_socket.close()

接受客户端发来的多条信息

TCP客户端%26服务端 - 图2

  1. ...
  2. while True:
  3. # 接收对方发送过来的数据
  4. recv_data = client_socket.recv(1024) # 接收1024个字节
  5. if recv_data:
  6. print('收到数据:%s' % recv_data.decode('gbk'))
  7. # 发送一些数据到客户端
  8. client_socket.send("好的,已经收到!~".encode('gbk'))
  9. else:
  10. break
  11. ...

允许客户端多次连接

TCP客户端%26服务端 - 图3

  1. # tcp 服务端:
  2. import socket
  3. # 1、创建套接字
  4. tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  5. # 2、绑定ip和端口
  6. tcp_server_socket.bind(("192.168.174.87", 8081))
  7. # 3、监听(让套接字由主动变为被动),只能接受客户端连接
  8. tcp_server_socket.listen(128)
  9. # 4、接收客户端连接
  10. # 此处while True作用是可以接收客户端多次连接
  11. while True:
  12. # 每个客户端连接成功后,分配一个新的套接字
  13. new_client_socket, ip_port = tcp_server_socket.accept()
  14. print("【新客户端来了】:", ip_port)
  15. # 5、开始数据传输, recv
  16. # 此处的while True,表示可以多次接收客户端的消息
  17. while True:
  18. recv_content = new_client_socket.recv(1024)
  19. # 如果客户端断开了连接,此时recv_content 接收到的数据为空
  20. if recv_content:
  21. # 保存客户端发来的信息
  22. re_text = recv_content.decode("gbk")
  23. print("收到客户端信息:", re_text)
  24. # 回复客户端
  25. new_client_socket.send("好的,收到.".encode())
  26. else:
  27. print("客户端可能断开连接!")
  28. break
  29. # 6、关闭和当前客户端的连接,当前客户端不能在进行通信了
  30. new_client_socket.close()
  31. # 7、关闭服务器(服务器不再接受新的客户端连接),服务器不再接收新的客户端连接(老的连接,继续服务)
  32. tcp_server_socket.close()

注意,仔细想想不难发现,这里同时还是只能有一个客户端接入进来。

TCP应用程序开发总结

  1. TCP 客户端程序想要和 TCP 服务端程序进行通信时必须要先建立连接
  2. TCP 客户端程序一般不需要绑定端口号(会自动随机分配),因为客户端是主动发起建立连接的。
  3. TCP 服务端程序必须绑定端口号,否则客户端找不到这个 TCP 服务端程序。
  4. 执行 listen 后的socket套接字是被动套接字,只负责接收新的客户端的连接请求,不能收发消息。
  5. 当 TCP 客户端程序和 TCP 服务端程序连接成功后, TCP 服务端会会客户端产生一个新的套接字,收发客户端消息使用该套接字。
  6. TCP服务端关闭 accept 返回的新套接字意味着和这个客户端已经通信完毕
  7. TCP服务端关闭自己的套接字意味着服务端关闭了,新的客户端不能连接服务端,但是之前已经接成功的客户端还能正常通信。
  8. 当客户端的套接字 close 后,服务器端的 recv 会解除阻塞,返回的数据长度为0;此时,服务端可以通过返回数据的长度来判断客户端是否已经下线,
  9. 反之,如果服务端为客户端创建的的套接字对象 close 后,客户端的 recv 也会解阻塞,返回的数据长度也为0