Socket编程_[套接字]

作者: 青蛙兄 分类: python,高阶 发布时间: 2019-12-29 15:32

Socket介绍

Socket[套接字]

Python中提供socket.py标准库,非常底层的接口库

Socket是一种通用的网络编程接口,和网络层次没有一一对应的关系

协议族

AF表示address Family,用于socket()第一个参数

名称含义
AF_INETIPV4
AF_INET6IPV6
AF_UNIXUnix Domain Socket,windows没有

Socket类型

名称含义
SOCK_STREAM面向连接的流套接字,默认值,TCP协议
SOCK_DGRAM无连接的数据报文套接字,UDP协议

TCP编程

Socket编程,需要两端,一般来说需要一个服务端,一个客户端,服务端称之为Server,客户端称之为Client

TCP服务端

服务器端编程步骤

1、创建Socke对象

2、绑定IP地址address和端口Port。bind()方法 IPv4地址为一个二元组(“IP地址字符串”,Port)  

3、开始监听,将在指定的IP的端口上监听。listen()方法  

4、获取用于传送数据的Socket对象  

   socket.accept( ) —> (socket object,address info)  

   accept方法阻塞等待客户端建立连接,返回一个新的Socket对象和客户端的二元组  

   地址是远程客户端的地址,IPv4中它是一个二元组(clientaddr,port)  

   1、接收数据  

   recv (bufsize [ ,flags] ) 使用缓存区接收数据  

   2、发送数据  

   send ( bytes ) 发送数据 

示例:(一个连接的数据反复收发)

import socket,threading,logging
logging.basicConfig(level=logging.INFO,format='%(thread)s %(message)s')

#TCP编程

#第一步,创建socket对象
socket = socket.socket()

ip = '127.0.0.1'
port = 9999
addr = (ip,port)

#第二步,绑定IP和端口
socket.bind(addr)

#第三步,监听此IP和端口
socket.listen()

#第四步,等待连接过来,默认是阻塞状态
conn,remove_addr = socket.accept()
logging.info(conn)
logging.info(remove_addr)

#第五步,接收数据
data = conn.recv(1024)
logging.info(data.decode())

msg = 'ack to {}'.format(data.decode())

#第六步,发送数据
conn.send(msg.encode())

#关闭连接
conn.close()

#关闭socket
socket.close()

使用类实现功能,并且能接受多个连接。

import threading
import logging
import socket

logging.basicConfig(level=logging.INFO, format='%(thread)s %(threadName)s %(message)s')


class ChatServer:
    def __init__(self, ip='127.0.0.1', port=8888):
        self.sock = socket.socket()
        self.address = (ip, port)
        self.clients = {}

    def start(self):
        self.sock.bind(self.address)
        self.sock.listen()

        threading.Thread(target=self._accept(), name='accept').start()

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

    def _accept(self):
        while True:
            conn, remove_addr = self.sock.accept()
            self.clients[remove_addr] = conn
            threading.Thread(target=self._recv, name='recv', args=(conn,)).start()

    def _recv(self, conn):
        while True:
            data = conn.recv(1024)
            logging.info(data.decode())

            msg = 'ack to {}'.format(data.decode())
            for c in self.clients.values():
                c.send(msg.encode())


cs = ChatServer()
cs.start()

发表评论

电子邮件地址不会被公开。