TCP编程

TCP协议 -> 传输控制协议

用途:主要用于网间传输的协议,分割处理报文并把结果包传到IP层,并接收处理IP曾传到的数据包。

TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议。

TCP通信模型中,在通信开始之前,一定要先建立相关的链接,才能发送数据,类似于生活中,"打电话""。

 

TCP通信流程


TCP服务器流程如下:

     1.socket 创建一个套接字

     2.bind 绑定ip和port

     3.listen 启动监听,使套接字变为可以被动连接,当关闭监听时,任何客户端都不能连接服务端

     4.accept 等待客户端的连接

     5.recv/send 接收/发送数据

     6.close 关闭socket对象

 

TCP连接三次握手


TCP断开连接四次挥手

TCP断开链接的过程和建立连接的过程比较类似,只不过中间的两步并不总是会合成一步走,所以它分成了4个动作。

上面有一个非常特殊的状态time_wait,它是主动关闭的一方在回复完对方的挥手后进入的一个长期状态,这个状态标准的

持续时间是4分钟,4分钟后才会进入到closed状态,释放套接字资源。不过在具体实现上这个时间是可以调整的。

单进程


TCP服务端流程

  1. socket 创建一个套接字
from socket import *
server = socket(AF_INET,SOCK_STREAM)

     2.bind 绑定ip和port

SERVERADDR = ('192.168.12.156',8888)
server.bind(SERVERADDR)

    3.listen 启动监听,使套接字变为可以被动连接,当关闭监听时,任何客户端都不能连接服务端

server.listen(n)              # n 代表可监听的客户端的数量,不写则默认为最大

    4.accept 等待客户端的连接

server.accept()

    5.recv/send 接收/发送数据

info = client.recv(1024)
print(info.decode('utf8'),client.getpeername())

inputstr = input('请输入发送信息:').encode('utf8')
client.send(inputstr)

    6.close 关闭socket对象

client.close()
server.close()

TCP客户端流程

from socket import *

client = socket(AF_INET,SOCK_STREAM)
client.connect(('192.168.12.156',8888))      # 连接到服务端

# 发送消息
inputstr = input('输入发送信息:').encode('utf8')
client.send(inputstr)
print('发送成功')

# 接收消息
while True:
    result = client.recv(1024)
    if len(result)>0:
        print(result)
    else:
        break

# 关闭客户端
client.close()

多线程


TCP服务端流程

from socket import *
import threading

def tread(cs):
    while True:
        result = cs.recv(1024)
        if len(result)>0:
            info = result.decode('gbk')
            # print(cs.getpeername(),info)
            to = info.split(':')[0]
            message = info.split(':')[1].encode('gbk')
            # print(to,message)
            if to in userdict.keys():
                userdict[to].send(message)
            else:
                cs.send("对方已离线,您不能发送消息".encode('gbk'))

        else:
            userdict.pop(str(cs.getpeername()[1]))
            print('剩余客户端',len(userdict))
            # print('断开',cs.getpeername())
            break


def tlisten(s):
    # 接收连接
    while True:
        client, clientaddr = s.accept()
        # 将连接的用户存到用户字典
        userdict[str(clientaddr[1])] = client
        print(clientaddr,"连接上了","用户列表",len(userdict))
        # print(clientaddr, '连接上了')
        # 第二个线程,用来接收client 发来的消息
        tr = threading.Thread(target=tread,args=(client,))
        tr.start()


if __name__=='__main__':
    try:
        userdict = {}

        # 构造服务端对象
        server = socket(AF_INET, SOCK_STREAM)
        # 绑定地址
        server.bind(('192.168.12.156', 8888))
        # 开启监听
        server.listen(10)
        print('开启监听')

        # 开启线程用于接受客户端连接
        tl = threading.Thread(target=tlisten,args=(server,))
        tl.start()

    except Exception as e:
        print(e)

TCP客户端流程

from socket import *
import threading

def twrite(ct):
    """发送"""
    try:
        while True:
            if not ct._closed:
                # 当进入while循环,还没有断开连接
                # input阻塞之后断开连接
                inputstr = input('请输入要发送的信息:').encode('utf8')
                if ct._closed:
                    break
                else:
                    ct.send(inputstr)
            else:
                break
    except Exception as e:
        print(e)


def tread(ct):
    """接收"""
    try:
        while True:
            result = ct.recv(1024)
            if len(result) > 0:
                print(result)
            else:
                ct.close()
                break
    except Exception as e:
        print(e)


if __name__=='__main__':
    try:
        client = socket(AF_INET, SOCK_STREAM)
        ADDRESS = ('192.168.12.156', 8888)
        ADDR = client.connect(ADDRESS)
        tw = threading.Thread(target=twrite, args=(client, ))
        tw.start()
        tr = threading.Thread(target=tread, args=(client,))
        tr.start()
        tw.join()
        tr.join()

        client.close()

    except Exception as e:
        print(e)

    print('已断开连接')

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值