Python-socket网络编程(一)


Python-socket网络编程

socket的基本认识:

socket(套接字):是一个通信端点,一种底层的网络接口。包含了很多套接字协议,可以参考文档:socket文档
socket 地址:进行网络通信的网络地址,主机-端口对,通过这个可以知道,要和谁进行通信

socket 类型:两类,面向连接的套接字和面向无连接的套接字
面向连接的套接字:

  • 通信前必须先建立一个连接
  • 提供序列化的、可靠的、不重复的数据交付,而且没有记录边界
  • 实现面向连接的套接字的基本协议是:传输控制协议(TCP)

无连接的套接字

  • 不用建立连接
  • 无法保证顺序性、可靠性或重复性,但是确实保存边界,消息是以整体进行发送的
  • 实现面向无连接套接字的基本协议是:用户数据报协议(UDP)

客户端/服务器架构
服务器:
就是一系列的硬件或软件,为一个或多个客户端(服务的用户)提供所需的服务。他存在唯一的目的就是等待客户端的请求,并响应他们。
客户端:
用户访问的界面或者说使用的软件,访问服务器,获取自己需要的信息

客户端对服务器的请求是一次性请求,服务器是需要一直运行下去的。客户端的每一次请求,都可以看做是一个事务。

socket模块提供的一些方法

名称描述
服务器套接字方法
s.bind()将地址(ip,port)绑定到套接字上
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.setblocking()设置套接字的阻塞或非阻塞模式
s.settimeout()设置阻塞套接字操作的超时时间
s.gettimeout()获取阻塞套接字操作的超时时间
面向文件的套接字方法
s.fileno()套接字的文件描述符
s.makefile()创建与套接字关联的文件对象

socket模块使用

要创建套接字,必须使用socket.socket()函数,一般语法如下:

socket(socket_family, socket_type, protocol=0)
# 参数解释:
    socket_family: 是AF_UNIX 或 AF_INET
    socket_type: 是SOCK_STREAM(TCP) 或 SOCK_DGRAM(UDP)
    protocol 通常省略,默认是0

创建TCP/IP套接字或UDP/IP套接字如下所示:

# 创建TCP/IP套接字
tcpSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 创建UDP/IP套接字
udpSocket = socket.socket(socket.AF_INET, socket.SOCK.DGRAM)	

使用套接字创建TCP服务器和客户端

"""
TCP服务器:
    1. 创建服务器套接字
    2. 套接字与地址绑定
    3. 监听连接
    4. 服务器无线循环等待连接
    5. 接受客户端连接
    6. 通信循环
    7. 对话(接受/发送)
    8. 关闭客户端套接字
    9. 关闭服务器套接字(可选)
"""

from socket import *
from time import ctime


# 地址和端口
HOST = ''
PORT = 21567
BUFFER_SIZE = 1024

ADDR = (HOST, PORT)


tcp_socket_server = socket(AF_INET, SOCK_STREAM)  # 创建服务器套接字
tcp_socket_server.bind(ADDR)  # 套接字与地址绑定
tcp_socket_server.listen(5)  # 监听连接

# 服务器无限循环等待连接
while True:
    print('waiting for connection....')
    tcp_client_server, addr = tcp_socket_server.accept()  # 接受客户端连接
    print('... connect from: ', addr)
    # 通信循环
    while True:
        data = tcp_client_server.recv(BUFFER_SIZE)  # 接受客户端发送的消息
        if not data:
            break
        tcp_client_server.send('[%s] %s'.encode('utf-8') % (bytes(ctime(), 'utf-8'), data))  # 向客户端发送信息

    tcp_client_server.close()  # 关闭客户端套接字

tcp_socket_server.close()  # 关闭服务器套接字(可选)

TCP客户端

"""
TCP 客户端:
    1. 创建客户端套接字
    2. 尝试连接服务器
    3. 通信循环
    4. 对话
    5. 关闭客户端套接字
"""

from socket import *

HOST = '127.0.0.1'
PORT = 21567
BUFFER_SIZE = 1024

ADDR = (HOST, PORT)

tcp_client_server = socket(AF_INET, SOCK_STREAM)  # 创建客户端套接字
tcp_client_server.connect(ADDR)  # 尝试连接服务器

# 通信循环
while True:
    data = input("> ")
    if not data:
        break
    tcp_client_server.send(data.encode('utf-8'))  # 客户端发送消息

    data = tcp_client_server.recv(BUFFER_SIZE)  # 客户端接受消息

    if not data:
        break

    print(data.decode('utf-8'))

tcp_client_server.close()  # 关闭客户端连接

使用套接字创建UDP服务器

from socket import *

HOST = '127.0.0.1'
PORT = 21567
Buffer_SIZE = 1024
ADDR = (HOST, PORT)


TARGET_PORT = 7777


def send_message(udp_server):
    """发送消息"""
    send_data = input('> ')
    udp_server.sendto(send_data.encode('utf-8'), (HOST, TARGET_PORT))


def receive_message(udp_server):
    """接收消息"""
    recv_data = udp_server.recvfrom(Buffer_SIZE)
    print("%s: %s" % (str(recv_data[1]), recv_data[0].decode('utf-8')))


def main():
    """主流程"""
    # 创建套接字
    udp_server = socket(AF_INET, SOCK_DGRAM)
    # 绑定端口
    udp_server.bind(ADDR)
    # 循环来处理事件
    while True:
        # 发送
        send_message(udp_server)
        # 接受并显示
        receive_message(udp_server)


if __name__ == '__main__':
    main()

使用套接字创建UDP客户端

from socket import *

HOST = '127.0.0.1'
PORT = 7777
BUFFER_SIZE = 1024
ADDR = (HOST, PORT)


def main():
    """主流程"""
    udp_client = socket(AF_INET, SOCK_DGRAM)
    udp_client.bind(ADDR)

    while True:
        msg, add = udp_client.recvfrom(BUFFER_SIZE)
        print("%s: %s" % (str(add), msg.decode('utf-8')))
        send_data = input('> ')

        udp_client.sendto(send_data.encode('utf-8'), add)


if __name__ == '__main__':
    main()
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值