TCPServer.py
1 #coding:utf-8 2 3 import socket 4 #s 等待链接 5 #c 实时通讯 6 s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) 7 #socket.AF_INET代表ipv4,socket.SOCK_STREAM代表tcp套接字 8 s.bind(('',23333)) 9 #绑定ip端口 如果为空,那就是所有网络号都可以 10 s.listen(5) 11 #最大同时5个人链接 12 13 14 print('[+]服务端开启') 15 16 while True: 17 try: 18 c,c_addr = s.accept() 19 #这里只能接受一个人链接,如果要链接多个客户端,需要开启多线程 20 #先接受客户端的连接 21 #阻塞形式 22 #client 通讯操作的套接字 23 #c_addr 是客户端的地址 24 25 print('有人来链接了:',c_addr) 26 while True: 27 data = c.recv(1024).decode('utf-8') 28 #客户端断开链接 会发送一个空字符串,长度为0 29 #data存储的是最大1024字节的数据 30 #要decode解码,以utf8的形式 31 if not data: 32 #判断接受到的数据,是不是为空,如果为空的话 就表示客户端已经断开链接 33 # print(type(data)) 34 # print('----------') 35 # print(len(data)) 36 # print('----------') 37 print('[+] 这个人走了') 38 break 39 #跳出循环,断开链接 40 print('这个人说',data) 41 msg = input('>>>') 42 #回复客户端 43 if msg == 'quit': 44 #如果 msg为 quit 就与客户端主动断开链接 45 print('[+] 与这个人主动断开链接.....') 46 break 47 c.send(msg.encode('utf-8')) 48 #发送的时候加码,以uff8的形式 49 c.close() 50 #断开与客户端的连接 51 except KeyboardInterrupt: 52 #ctrl+c终止程序 防止卡主 53 print('检测到异常 即将推出') 54 break 55 56 print('[+] 服务器关闭') 57 s.close()
TCPclient.py
1 #coding:utf-8 2 3 import socket 4 client = socket.socket(socket.AF_INET,socket.SOCK_STREAM) 5 #创建一个客户端链接,socket.AF_INET代表ipv4,socket.SOCK_STREAM代表tcp套接字 6 client.connect(('127.0.0.1',23333)) 7 #客户端链接 8 print('[+] 链接成功') 9 #链接成功显示 10 while True: 11 msg = input('>>>') 12 if msg == 'quit': 13 #如果输入的信息是quit 就退出链接 14 break 15 if len(msg) == 0:#如果直接输入的一个回车的话 16 #就重新输入,因为不能发送空 ,发送空的花 客户端会卡住 17 continue 18 client.send(msg.encode('utf-8')) 19 #客户端发送信息msg 以utf8格式发送数据 20 data = client.recv(1024).decode('utf-8') 21 if not data: 22 #如果数据为空/0 23 #服务器主动断开s 24 break 25 print('[+] 服务器主动断开了链接......') 26 27 print('服务器发来:',data) 28 29 30 print('[+] 链接关闭...') 31 32 client.close()
#注意事项:
- 网络中传输数据的格式是二进制,所以传输的数据都要编码和解码,默认是UTF-8
- 代码中发送和接受的数据最大为1024字节,如果大于这个数据,数据会留在缓冲区,等待下一次发送,如果要一次性发送,需要用到循环语句
- 客户端和服务器如果断开连接的话,会发送一个空字符串,长度为0,然后对方用一个判断语句来判断是否断开链接
- 发送的数据不能为空,假如直接按回车的话 会发送空,是不行的,程序会卡住,input对于用户输入的换行是不会读入的,因为我们都知道input是以换行作为输入结束的标志的。
- 对于空消息:tcp是基于数据流的,于是收发的消息不能为空,这就需要在客户端和服务端都添加空消息的处理机制,防止程序卡住,
- QQ也是这样的,不能发送为空的内容
-
服务器套接字创建模型:
-
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
-
s.bind( ('', 8000) ):绑定该套接字有效地址和端口
-
参数是一个元组
-
-
s.listen(5) 开启服务器
-
c,c_addr = s.accept() 阻塞等待客户端连接
-
c:客户端来访套接字来与客户端进行交流
-
c_addr:客户来访地址,(ip,port)
-
-
while:具体和这个客户端进行沟通
-
c.send(msg)
-
发送数据
-
msg == byte
-
-
data = c.recv(1024): -> bytes
-
接收数据
-
接收到的也是个二进制
-
-
取决于客户端发来的数据如果为空,那么就可以关闭与他的连接了。
-
-
c.close()
-
关闭套接字 释放资源
-
-
s.close()
-
-
-
-
客户端套接字模型:
-
c = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
-
c.connect( (ip,port) )
-
47.104.224.67
-
8000
-
-
c.recv() 接收
-
c.send() 发送
-
c.close()
-
关闭套接字 断开连接 释放资源
-
-
-
-
单进程模型下,我们写的代码,同一时间只能处理一个用户的来访信息
-
TCP是要构成连接的
-