signed

QiShunwang

“诚信为本、客户至上”

python学习笔记(十一)——网络编程

2021/5/14 23:26:13   来源:

python 可以使用 socket 模块进行网络通信。

在python开发文档中可以查询到有关该模块的参考 https://docs.python.org/zh-cn/3/library/socket.html?highlight=socket#module-socket

一、使用 socket.socket()函数创建套接字

socket(socket_family, socket_type, protocol=0)
‘’‘
socket_family 可选 AF_UNIX 或 AF_INET
# AF_UNIX用于同一台机器上的进程间通信
# AF_INET对于IPV4协议的TCP和UDP
socket_type 可选 SOCK_STREAM 或 SOCK_DGRAM
# SOCK_STREAM 流式套接字,即TCP
# SOCK_DGRAM 数据报套接字,即UDP
protocol 通常省略,默认为 0
‘’’
  • 创建TCP/IP套接字
tcpSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  • 创建 UDP/IP 套接字
udpSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

socket对象内置方法

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

网络编程示例

1. TCP程序

1.1. 简单的服务器应答程序

功能:客户端连接服务端后,服务端发送“你好”到客户端,客户端接收数据并打印到屏幕上。

# server.py
from socket import socket

ss = socket() # 创建服务器套接字
ss.bind(("127.0.0.1",6000))    # 套接字与地址绑定
ss.listen(5)                    # 监听连接
while True:   # 服务器无限循环
    cs,c_addr = ss.accept() # 接受客户端连接
    data = cs.send("你好..".encode("utf-8"))  # 使用字节流传输数据
    cs.close() # 关闭客户端套接字
ss.close() # 关闭服务器套接字 
from socket import socket

s = socket() # 默认参数socket.AF_INET, socket.SOCK_STREAM
s.connect(("127.0.0.1",6000))
data = s.recv(1024)		# 最大接收长度
print(data.decode("utf-8"))	
s.close()
1.2. 服务器返回当前时间程序
import socket, time

serversocket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
serversocket.bind(('',8888))    # localhost/127.0.0.1
serversocket.listen(5)

while True:
    (clientsocket, address) = serversocket.accept() #等待客户端连接
    data = clientsocket.recv(4096)          #接收姓名
    print("打印: ", data.decode())         # 将字节流(bitys)转换为str
    datetime = time.asctime()+'\n'
    replay = 'Hello'.encode() + data;   #回复:问候消息
    replay += 'My time is '.encode() + datetime.encode()#回复:当前服务器时间
    clientsocket.send(replay)           # 发送消息
    clientsocket.close()#关闭连接
import os
import sys
import socket

sock = socket.socket(socket.AF_INET,socket . SOCK_STREAM)
sock.connect((sys.argv[1],8888))             #服务器地址由命令行指定
sock.send( (os.getlogin() + '\n').encode()) #发送姓名
message = sock.recv(4096)       #接收响应
print(message.decode())         #打印结果
sock.close()#关闭连接

# 编译命令 python client.py localhost

在这里插入图片描述

2.UDP程序

echo程序,客户端向服务器端发送数据,服务器将该数据再次发送会=回给客户端。

# ser.py
import socket

ss = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)   # udp
ss.bind(("127.0.0.1", 6001))     # 绑定本地地址
while True:
    data,addr = ss.recvfrom(1024)
    print("from",addr,"recv:", data.decode("utf-8"))
    ss.sendto(data, addr)
# cli.py
import socket
                                    # udp
ss = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
ser_addr = ("127.0.0.1",6001)     # 服务器地址
while True:
    sendbuf = input("输入:")
    if sendbuf == "exit":
        break;
    ss.sendto(sendbuf.encode("utf-8"), ser_addr)
    data,_ = ss.recvfrom(1024)
    print("recv:", data.decode("utf-8"))

在这里插入图片描述