Python第四周之网络编程TCP (服务器/客户端; 线程下载图片;线程版服务器和客户端(单人、多人)) UDP
# 网络编程
# 计算机网络, 把多台独立自主的计算机,连接到网络,实现资源的共享
# Internet网,(互联网)eniac 1946美国大学第一台电子计算机
#
# 一个TCP报文除了包含要传输的数据外,还包含源IP地址和目标IP地址,源端口和目标端口。
# ISO协议
# 传数据,切小片,校验 TCP - 保证正确 UDP - 速度快,但是会有误差。
# 每个联网的设备都有IP地址。
# HTTP -- Hyper-Text Transfer Protocol-80
# SMTP - Simple Mail Transfer Protocol-25
# POP3 - Post Offce Protocol verdion3-110
# IMAP -Internet Mail Access Protocol
# HTTPS-443
# 再应用层,利用TCP和UDP来传输数据。 做法,套接值。
TCP 服务器
# 做一个联网的应用 # netstat 查看所有端口 telnet连接别人的IP from socket import socket, AF_INET, SOCK_STREAM import datetime def main(): # 规定:ipv4的协议 # server = socket(AF_INET, SOCK_STREAM) 可以省略 # 1.创建一个基于TCP协议的套接字对象。 # 因为我们做的是应用级的产品或服务,所以可以利用现有的传输服务来实现数据传输。 server = socket() # 2.绑定在IP地址(网络上主机的身份标识),和端口(用来区分不同服务的IP地址的扩展) server.bind(('10.7.189.77', 6791)) # 包含ip地址和端口号,对应电脑和服务-应用。 # 3.开始监听客户端的连接。 server.listen(512) # 512 - 为等待队列的大小。 print('服务器已经启动!正在监听。。。') while True: # 通过accept方法,接受客户的连接,accept是一个阻塞式的方法: # 如果没有客户端连接,那么accept方法会让代码阻塞,直到有客户段连接成功才返回-- 元组, # accept 方法返回一个元组,元组中第一个值代表客户端的对象, # 元组的第二个值又是一个元组,其中有的客户端的ip地址和端口。 client, addr = server.accept() print(client) print(addr, '连接成功') t = datetime.datetime.now() print(t) client.send(str(t).encode('utf-8')) #client.close() if __name__ == '__main__': main()
TCP客户端
from socket import socket def main(): client = socket() client.connect(('10.7.189.77', 6790)) data = client.recv(1024) print(type(data)) print(data.decode('utf-8')) if __name__ == '__main__': main()
多线程下载图片
import json import requests from threading import Thread class PictureLoad(Thread): def __init__(self, url): super(PictureLoad, self).__init__() self._url = url def run(self): resp = requests.get(self._url) filename = self._url[self._url.rfind('/') + 1:] try: with open(filename, 'wb') as fs: fs.write(resp.content) except IOError as e: print(e) def main(): resp = requests.get('http://api.tianapi.com/meinv/?key=81085f5747a59581327b29d1bccfb925&num=10') my_dict = json.loads(resp.text) threads = [] for temp in my_dict['newslist']: pic_url = temp['picUrl'] pictureload = PictureLoad(pic_url) pictureload.start() # resp = PictureLoad(pic_url).start() threads.append(pictureload) for thread in threads: thread.join() print('图片下载完成') if __name__ == '__main__': main()
单人线程版聊天室
#服务器
from socket import socket from threading import Thread class Accept(Thread): def __init__(self, client): super(Accept, self).__init__() self._client = client def run(self): data = self._client.recv(1024) return print(data.decode('utf-8')) class Send(Thread): def __init__(self, client, sentence): super(Send, self).__init__() self._sentence = sentence self._client = client def run(self): self._client.send(str(self._sentence).encode('utf-8')) def main(): server = socket() # 创建对象 server.bind(('10.7.189.77', 6672)) # 绑定IP和端口 server.listen(512) # 同时连入数,最大等待数 print('程序已经启动,正在监听。。。。') while True: client, addr = server.accept() # 接受连入的对象,前面为服务器的地址,后面为客户端的IP print(addr, '已经连接') while True: accept = Accept(client) # 使用线程接受消息 accept.start() # print(data.decode('utf-8')) #data = client.recv(1024) #print(data.decode('utf-8')) t = input('请输入你要发送的话:') # 发送消息 send = Send(client, t) send.start() if __name__ == '__main__': main()
# 客户端
from socket import socket from threading import Thread class Send(Thread): def __init__(self, client, me): super(Send, self).__init__() self._client = client self._me = me def run(self): self._client.send(str(self._me).encode('utf-8')) def main(): client = socket() # 1.创建对象 client.connect(('10.7.189.130', 8080)) # 2.连接服务器 print('连接成功') while True: me = input('请输入你要说的话:') # 发送消息 #client.send(str(me).encode('utf-8')) send = Send(client, me) # 使用线程 send.start() data = client.recv(1024) print(data.decode('utf-8')) if __name__ == '__main__': main()
# 多人版线程聊天
# 服务器
from socket import socket from threading import Thread def main(): class RefreshScreenThread(Thread): def __init__(self, client): super(RefreshScreenThread, self).__init__() self._client = client def run(self): while True: data = self._client.recv(1024) print(data.decode('utf-8')) # 一直接受消息并打印出来 myclient = socket() # 创建对象 myclient.connect(('10.7.189.130', 11110)) # 连接服务器 RefreshScreenThread(myclient).start() # 刷新接受到的消息 nickname = input('请输入你的昵称:') running = True while running: content = input('请发言:') if content == 'byebye': running = False else: content = nickname + ':' + content myclient.send(str(content).encode('utf-8')) # 发送消息 if __name__ == '__main__': main()
# 客户端
from socket import socket from threading import Thread def main(): class Clienthandler(Thread): def __init__(self, client): super(Clienthandler, self).__init__() self._client = client def run(self): while True: try: data = self._client.recv(1024) # 接受二进制数据 for client in clients: client.send(data) #print(data.decode('utf-8')) if data.decode('utf-8') == 'byebye': clients.remove(self._client) self._client.close() except Exception as ex_msg: print(ex_msg) clients.remove(self._client) break serverce = socket() # 1. 创建套接制对象 # AF_INET ip4 SOCK_STREAM = TCP 为默认值。 # Python 命令行参数-- sys.argv serverce.bind(('10.7.189.77', 8891)) # 2. 绑定地址, ip(127.0.0.1\localhost)和ip地址的扩展--端口(1024-65535) serverce.listen(512) # 最大连入数,等待数。 print('用户连入,开始监听。。。') clients = [] while True: cuur_client, addr = serverce.accept() # 阻塞式的方法,接受用户的请求。 clients.append(cuur_client) # 把连入的用户,放到一个列表里。 Clienthandler(cuur_client).start() if __name__ == '__main__': main()
UDP
发消息
from socket import socket, SOCK_DGRAM from time import sleep def main(): sender = socket(type=SOCK_DGRAM) # UDP套接制 速度快,但是容易丢失 1. 创建对象 with open('zms.jpg', 'rb') as f: data = f.read() # f.seek() # 标记,从头移动到尾部 # f.tell # data_len = len(data) total = 0 while total < data_len: sender.sendto(data[total:total+1023], ('10.7.189.77', 8899)) total += 1024 sleep(0.0001) if __name__ == '__main__': main()
接消息
from socket import socket, SOCK_DGRAM def main(): receiver = socket(type=SOCK_DGRAM) receiver.bind(('10.7.189.77', 8899)) # 2.我在这个端口等着你给我数据 data = bytes() while True: seg, addr = receiver.recvfrom(1024) # 3. 收数据,指定缓冲区大小。 data += seg # 数据的拼接 if len(data) >= 27112: break with open('zms1.jpg', 'wb') as f: f.write(data) print('图片已接收') # receiver.recvfrom() if __name__ == '__main__': main()