大数据 爬虫Python AI Sql

Python-网络编程

2019-08-01  本文已影响4人  葱花思鸡蛋
1.TCP/IP简介:

互联网上每个计算机的唯一标识就是IP地址,类似123.123.123.123。如果一台计算机同时接入到两个或更多的网络,比如路由器,它就会有两个或多个IP地址,所以,IP地址对应的实际上是计算机的网络接口,通常是网卡。

IP协议负责把数据从一台计算机通过网络发送到另一台计算机。数据被分割成一小块一小块,然后通过IP包发送出去。由于互联网链路复杂,两台计算机之间经常有多条线路,因此,路由器就负责决定如何把一个IP包转发出去。IP包的特点是按块发送,途径多个路由,但不保证能到达,也不保证顺序到达。

8572700-bbfc3d88d8817a2e.png

TCP协议则是建立在IP协议之上的。TCP协议负责在两台计算机之间建立可靠连接,保证数据包按顺序到达。TCP协议会通过握手建立连接,然后,对每个IP包编号,确保对方按顺序收到,如果包丢掉了,就自动重发。

许多常用的更高级的协议都是建立在TCP协议基础上的,比如用于浏览器的HTTP协议、发送邮件的SMTP协议等。

一个IP包除了包含要传输的数据外,还包含源IP地址和目标IP地址,源端口和目标端口。

端口有什么作用?在两台计算机通信时,只发IP地址是不够的,因为同一台计算机上跑着多个网络程序。一个IP包来了之后,到底是交给浏览器还是QQ,就需要端口号来区分。每个网络程序都向操作系统申请唯一的端口号,这样,两个进程在两台计算机之间建立网络连接就需要各自的IP地址和各自的端口号。

一个进程也可能同时与多个计算机建立链接,因此它会申请很多端口。

TCP/IP协议簇,包括应用层协议(http 超文本传输协议、DNS域名解析、文本传输协议TFTP等)、网络层协议(IP协议、ICMP控制信息协议、ARP地址解析协议、RARP反向地址协议)、传输层(TCP协议、UDP协议)

TCP:

UDP:

TCP/UDP使用场景:
TCP:http文件传输协议、文件的上传下载、发送邮件
UDP:QQ语音、QQ视频、微信

2.基于TCP的socket聊天室实现
8572700-be62f1c1f6544e5f.png

服务端实现:

import socket
import threading

class chatRoom:
    def __init__(self,ip='127.0.0.1',port=9999):
        self.addr = (ip,port)
        self.server = socket.socket()
        self.clients = {}

    def start(self):
        self.server.bind(self.addr)
        self.server.listen()
        # 子线程处理客户端连接,防止阻塞主线程
        threading.Thread(target=self.accept(),name='accept').start()

    def accept(self):
        # 监听客户端的连接
        while True:
            # 没有客户端连接阻塞线程,有连接返回新的socket和客户端ip
            sock,ip = self.server.accept()
            # 把socket 装入容器
            self.clients[ip] = sock

            # 监听到连接创建一个socket,与客户端交互,子线程循环监听数据的接收
            threading.Thread(target=self.recive(sock),name='recive').start()


    def recive(self,sock:socket.socket):
        while True:
            try:
                # data 是字节
                data = sock.recv(1024)
                print(data.decode())
            except Exception as e:
                print('客户端异常,连接失败')
                data = b'quit'

            # 客户端输入quit,断开socket链接
            if data == b'quit':
                # 根据key,移除想要退出群聊的客户端
                self.clients.pop(sock.getpeername())
                socket.close()
                break


            # 收到数据发送到每一个客户端
            for sock in self.clients.values():
                # sock.getpeername() 获取远程客户端地址和端口元组形式
                sock.send('你是猪吗{}'.format(sock.getpeername()).encode('utf-8'))



    def stop(self):
        for sock in self.clients.values():
            sock.close()

        self.server.close()


if __name__ == '__main__':

    chatServer = chatRoom()
    chatServer.start()
    

客户端实现:

import  socket

class client:
   def __init__(self):
       self.socket = socket.socket()
       self.socket.connect(('127.0.0.1',9999))

   def sendMsg(self,msg):
       self.socket.send('客户端:{}'.format(msg).encode('uft-8'))


   def recvMsg(self):
       data = self.socket.recv(1024)
       if data:
           print('服务器:'.format(data.decode('utf-8')))
           return True
       return False

   def run(self):
       self.sendMsg('我来了哈哈哈')
       while True:
           if self.recvMsg():
               msg = input("\n客户端:")
               self.sendMsg(msg)


if __name__ == '__main__':
       c = client()
       c.run()


Mac 查看端口占用情况命令:

lsof -i #全部端口占用进程
lsof -i :9999 #查看指定端口占用进程 ,i后跟一个空格
kill pid #kill 加上占用端口的进程PID,就可以杀掉占用端口的进程

3.基于UDP的socket实现流程图
8572700-d43133eb020a3c8e.png
上一篇 下一篇

猜你喜欢

热点阅读