python关于Socket编程方法

2019-07-25  本文已影响0人  叶扬风起
socket
1、创建

socket.socket(family=AF_INET, type=SOCK_STREAM, protocal=0)

注:这些常量都是套接字类型,应用于socket()函数中的第二个参数中.根据系统的不同,可能有更多的常数。(只有SOCK_STREAMSOCK_DGRAM似乎通常很有用。

#创建 TCP/IP 套接字
tcpSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#创建 UDP/IP 套接字
udpSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
2. TCP Socket通信

如下图所示,TCP通信的基本步骤如下:
服务端:socket---bind---listen---while(True){---accept----recv---send---}---close
客户端:socket----------------------------------------connect---send---recv-------close


TCP Socket通信
socket.socket([family[, type[, proto]]])
    family : AF_INET (默认ipv4), AF_INET6(ipv6) or AF_UNIX(Unix系统进程间通信)
    type : SOCK_STREAM (TCP), SOCK_DGRAM(UDP) .
    protocol : 一般为0或者默认

如果socket创建失败会抛出一个socket.error异常</code>

s.bind(address)
    s为socket.socket()返回的套接字对象
    address为元组(host,port)
        host: ip地址, 为一个字符串
        post: 自定义主机号, 为整型

 2). listen函数
  使服务器的这个端口和IP处于监听状态,等待网络中某一客户机的连接请求。如果客户端有连接请求,端口就会接受这个连接。

s.listen(backlog)
  s为socket.socket()返回的套接字对象
  backlog : 操作系统可以挂起的最大连接数量。该值至少为1,大部分应用程序设为5就可以了

 3). accept函数
  接受远程计算机的连接请求,建立起与客户机之间的通信连接。服务器处于监听状态时,如果某时刻获得客户机的连接请求,此时并不是立即处理这个请求,而是将这个请求放在等待队列中,当系统空闲时再处理客户机的连接请求。

s.accept()
    s为socket.socket()返回的套接字对象
    返回(conn,address),其中conn是新的套接字对象,可以用来接收和发送数据。address是连接客户端的地址
s.connect(address)
    s为socket.socket()返回的套接字对象
    address : 格式为元组(hostname,port),如果连接出错,返回socket.error错误
#接收远端主机传来的数据
s.recv(bufsize[,flag])
    s为socket.socket()返回的套接字对象
    bufsize : 指定要接收的数据大小
    flag : 提供有关消息的其他信息,通常可以忽略
    返回值为数据以字符串形式

 2). send函数

#发送数据给指定的远端主机
s.send(string[,flag])
    s为socket.socket()返回的套接字对象
    string : 要发送的字符串数据
    flag : 提供有关消息的其他信息,通常可以忽略
    返回值是要发送的字节数量,该数量可能小于string的字节大小。
s.sendall(string[,flag])
    #完整发送TCP数据。将string中的数据发送到连接的套接字,但在返回之前会尝试发送所有数据。
    返回值 : 成功返回None,失败则抛出异常。

 3). close函数

#关闭套接字
s.close()
  s为socket.socket()返回的套接字对象
import socket

phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #买手机
phone.bind(('127.0.0.1',8080)) #插电话卡

phone.listen(5) #开机,backlog

print('starting....')
while True:
    conn,addr = phone.accept() #接电话
    print('接到来自%s的电话' %addr[0])
    while True:
        client_msg=conn.recv(1024) #收消息
        if len(client_msg) == 0:break  #如果不加,那么正在链接的客户端突然断开,recv便不再阻塞,死循环发生
        print('client msg: %s' %client_msg)
        conn.send(client_msg.upper()) #发消息
    conn.close()
phone.close()

 2). 客户端代码


import socket
ip_port = ('127.0.0.1',8081)    #电话卡
BUFSIZE=1024
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)  #买手机
s.bind(ip_port) #手机插卡
s.listen(5) #手机待机

while True:                  #新增接收链接循环,可以不停的接电话
    conn,addr=s.accept()    #手机接电话
    print('接到来自%s的电话' %addr[0])
    while True:                 ##新增通信循环,可以不断的通信,收发消息
        msg=conn.recv(BUFSIZE)  #听消息,听话
        if len(msg) == 0:break  #如果不加,那么正在链接的客户端突然断开,recv便不再阻塞,死循环发生
        print(msg,type(msg))
        conn.send(msg.upper())  #发消息,说话
    conn.close()                #挂电话
s.close()               #手机关机
3. TCP UDP通信

UDP通信流程图如下:
服务端:socket---bind---recvfrom---sendto---close
客户端:socket------------sendto---recvfrom---close


UDP通信
socket.socket([family[, type[, proto]]])
    family : AF_INET (默认ipv4), AF_INET6(ipv6) or AF_UNIX(Unix系统进程间通信)
    type : SOCK_STREAM (TCP), SOCK_DGRAM(UDP) .
    protocol : 一般为0或者默认

如果socket创建失败会抛出一个socket.error异常</code>

#发送UDP数据, 将数据发送到套接字
s.sendto(string[,flag],address)
s为socket.socket()返回的套接字对象
address : 指定远程地址, 形式为(ipaddr,port)的元组
flag : 提供有关消息的其他信息,通常可以忽略
返回值 : 发送的字节数。

 2). recvfrom函数

#接受UDP套接字的数据, 与recv()类似
s.recvfrom(bufsize[.flag])
返回值 : (data,address)元组, 其中data是包含接收数据的字符串,address是发送数据的套接字地址
bufsize : 指定要接收的数据大小
flag : 提供有关消息的其他信息,通常可以忽略

 3). close函数

#关闭套接字
s.close()
  s为socket.socket()返回的套接字对象
import socket
ip_port=('127.0.0.1',8081)
udp_server_sock=socket.socket(socket.AF_INET,socket.SOCK_DGRAM) #买手机
udp_server_sock.bind(ip_port)

while True:
    qq_msg,addr=udp_server_sock.recvfrom(1024)
    print('来自[%s:%s]的一条消息:\033[1;44m%s\033[0m' %(addr[0],addr[1],qq_msg.decode('utf-8')))
    back_msg=input('回复消息: ').strip()

    udp_server_sock.sendto(back_msg.encode('utf-8'),addr)

 2). 客户端代码
客户端1

import socket
BUFSIZE=1024
udp_client_socket=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)

qq_name_dic={
    'TOM':('127.0.0.1',8081),
    'JACK':('127.0.0.1',8081),
    '一棵树':('127.0.0.1',8081),
    '武大郎':('127.0.0.1',8081),
}


while True:
    qq_name=input('请选择聊天对象: ').strip()
    while True:
        msg=input('请输入消息,回车发送: ').strip()
        if msg == 'quit':break
        if not msg or not qq_name or qq_name not in qq_name_dic:continue
        udp_client_socket.sendto(msg.encode('utf-8'),qq_name_dic[qq_name])

        back_msg,addr=udp_client_socket.recvfrom(BUFSIZE)
        print('来自[%s:%s]的一条消息:\033[1;44m%s\033[0m' %(addr[0],addr[1],back_msg.decode('utf-8')))

udp_client_socket.close()

客户端2

import socket
BUFSIZE=1024
udp_client_socket=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)

qq_name_dic={
    'TOM':('127.0.0.1',8081),
    'JACK':('127.0.0.1',8081),
    '一棵树':('127.0.0.1',8081),
    '武大郎':('127.0.0.1',8081),
}


while True:
    qq_name=input('请选择聊天对象: ').strip()
    while True:
        msg=input('请输入消息,回车发送: ').strip()
        if msg == 'quit':break
        if not msg or not qq_name or qq_name not in qq_name_dic:continue
        udp_client_socket.sendto(msg.encode('utf-8'),qq_name_dic[qq_name])

        back_msg,addr=udp_client_socket.recvfrom(BUFSIZE)
        print('来自[%s:%s]的一条消息:\033[1;44m%s\033[0m' %(addr[0],addr[1],back_msg.decode('utf-8')))

udp_client_socket.close()

常见的套接字对象方法和属性

名 称 描 述 服务器套接字方法
s.bind() 将地址(主机名、端口号对)绑定到套接字上
s.listen() 设置并启动 TCP 监听器
s.accept() 被动接受 TCP 客户端连接,一直等待直到连接到达(阻塞)
客户端套接字方法
s.connect() 主动发起 TCP 服务器连接
s.connect_ex() connect()的扩展版本,此时会以错误码的形式返回问题,而不是抛出一个异常
普通的套接字方法
s.recv() 接收 TCP 消息
s.recv_into() 接收 TCP 消息到指定的缓冲区
s.send() 发送 TCP 消息
s.sendall() 完整地发送 TCP 消息
s.recvfrom() 接收 UDP 消息
s.recvfrom_into() 接收 UDP 消息到指定的缓冲区
s.sendto() 发送 UDP 消息
s.getpeername() 连接到套接字( TCP)的远程地址
s.getsockname() 当前套接字的地址
s.getsockopt() 返回给定套接字选项的值
s.setsockopt() 设置给定套接字选项的值
s.shutdown() 关闭连接
s.close() 关闭套接字
s.detach() 在未关闭文件描述符的情况下关闭套接字,返回文件描述符
s.ioctl() 控制套接字的模式(仅支持 Windows)
面向阻塞的套接字方法
s.setblocking() 设置套接字的阻塞或非阻塞模式
s.settimeout() 设置阻塞套接字操作的超时时间
s.gettimeout() 获取阻塞套接字操作的超时时间
面向文件的套接字方法
s.fileno() 套接字的文件描述符
s.makefile() 创建与套接字关联的文件对象
数据属性
s.family 套接字家族
s.type 套接字类型
s.proto 套接字协议
上一篇下一篇

猜你喜欢

热点阅读