ocket是基于C/S架构的,也就是说进行socket网络编程,通常需要编写两个py文件,一个服务端,一个客户端。

首先,导入Python中的socket模块: import socket

Python中的socket通信逻辑如下图所示(图片来自网络):

想要学习Python?Python学习交流群:660193417 满足你的需求,资料都已经上传群文件,可以自行下载!

这张逻辑图,是整个socket编程中的重点的重点,你必须将它理解、吃透,然后刻在脑海里,真正成为自己记忆的一部分!很多人说怎么都学不会socket编程,归根到底的原因就是没有“死记硬背”知识点。

在Python中,import socket后,用socket.socket()方法来创建套接字,语法格式如下:

  1. sk = socket.socket([family[, type[, proto]]])

参数说明:

  • family: 套接字家族,可以使AF_UNIX或者AF_INET。
  • type: 套接字类型,根据是面向连接的还是非连接分为SOCK_STREAM或SOCK_DGRAM,也就是TCP和UDP的区别。
  • protocol: 一般不填默认为0。

直接socket.socket(),则全部使用默认值。

下面是具体的参数定义:

通过s = socket.socket()方法,我们可以获得一个socket对象s,也就是通常说的获取了一个“套接字”,该对象具有一下方法:

注意事项:

Python3以后,socket传递的都是bytes类型的数据,字符串需要先转换一下,string.encode()即可;另一端接收到的bytes数据想转换成字符串,只要bytes.decode()一下就可以。

在正常通信时,accept()和recv()方法都是阻塞的。所谓的阻塞,指的是程序会暂停在那,一直等到有数据过来。

socket编程思路:

服务端:

创建套接字,绑定套接字到本地IP与端口:socket.socket(socket.AF_INET,socket.SOCK_STREAM) , s.bind()
开始监听连接:s.listen()
进入循环,不断接受客户端的连接请求:s.accept()
接收传来的数据,或者发送数据给对方:s.recv() , s.sendall()
传输完毕后,关闭套接字:s.close()

客户端:

创建套接字,连接服务器地址:socket.socket(socket.AF_INET,socket.SOCK_STREAM) , s.connect()
连接后发送数据和接收数据:s.sendall(), s.recv()
传输完毕后,关闭套接字:s.close()
Python的socket编程,通常可分为TCP和UDP编程两种,前者是带连接的可靠传输服务,每次通信都要握手,结束传输也要挥手,数据会被检验,是使用最广的通用模式;后者是不带连接的传输服务,简单粗暴,不加控制和检查的一股脑将数据发送出去的方式,但是传输速度快,通常用于安全和可靠等级不高的业务场景,比如文件下载。

TCP编程

服务器端:

  1. #!/usr/bin/env python
  2. # -*- coding:utf-8 -*-
  3. '''
  4. 想要学习Python?Python学习交流群:660193417满足你的需求,资料都已经上传群文件,可以自行下载!
  5. '''
  6. import socket
  7. ip_port = ('127.0.0.1', 9999)
  8. sk = socket.socket() # 创建套接字
  9. sk.bind(ip_port) # 绑定服务地址
  10. sk.listen(5) # 监听连接请求
  11. print('启动socket服务,等待客户端连接...')
  12. conn, address = sk.accept() # 等待连接,此处自动阻塞
  13. while True: # 一个死循环,直到客户端发送‘exit’的信号,才关闭连接
  14. client_data = conn.recv(1024).decode() # 接收信息
  15. if client_data == "exit": # 判断是否退出连接
  16. exit("通信结束")
  17. print("来自%s的客户端向你发来信息:%s" % (address, client_data))
  18. conn.sendall('服务器已经收到你的信息'.encode()) # 回馈信息给客户端
  19. conn.close() # 关闭连接

客户端:

  1. #!/usr/bin/env python
  2. # -*- coding:utf-8 -*-
  3. import socket
  4. ip_port = ('127.0.0.1', 9999)
  5. s = socket.socket() # 创建套接字
  6. s.connect(ip_port) # 连接服务器
  7. while True: # 通过一个死循环不断接收用户输入,并发送给服务器
  8. inp = input("请输入要发送的信息: ").strip()
  9. if not inp: # 防止输入空信息,导致异常退出
  10. continue
  11. s.sendall(inp.encode())
  12. if inp == "exit": # 如果输入的是‘exit’,表示断开连接
  13. print("结束通信!")
  14. break
  15. server_reply = s.recv(1024).decode()
  16. print(server_reply)
  17. s.close() # 关闭连接

上面这个例子,基本能够展示出socket通信的机制。套接字的创建和关闭,服务器的绑定和监听,客户端的连接,这些都是固定套路,没什么难点。关键之处在于循环内部的收发逻辑,这里才是重点,需要根据你自己的业务需求,正确编写。这个过程中,一定要注意,收发是一一对应的,有发就要有收,并且recv()方法默认是阻塞的。

大家可以在自己的环境中测试上面的例子,并加入更多的内容,不断地进行尝试。然而试过之后,你们会发现,虽然服务器和客户端在一对一的情况下,工作良好,但是,如果有多个客户端同时连接同一个服务器呢?结果可能不太令人满意,因为服务器无法同时对多个客户端提供服务。为什么会这样呢?因为Python的socket模块,默认情况下创建的是单进程单线程,同时只能处理一个连接请求,如果要实现多用户服务,那么需要使用多线程机制。

下面我们使用Python内置的threading模块,配合socket模块创建多线程服务器。客户端的代码不需要修改,可以继续使用。

  1. #!/usr/bin/env python
  2. # -*- coding:utf-8 -*-
  3. import socket
  4. import threading # 导入线程模块
  5. def link_handler(link, client):
  6. """
  7. 该函数为线程需要执行的函数,负责具体的服务器和客户端之间的通信工作
  8. :param link: 当前线程处理的连接
  9. :param client: 客户端ip和端口信息,一个二元元组
  10. :return: None
  11. """
  12. print("服务器开始接收来自[%s:%s]的请求...." % (client[0], client[1]))
  13. while True: # 利用一个死循环,保持和客户端的通信状态
  14. client_data = link.recv(1024).decode()
  15. if client_data == "exit":
  16. print("结束与[%s:%s]的通信..." % (client[0], client[1]))
  17. break
  18. print("来自[%s:%s]的客户端向你发来信息:%s" % (client[0], client[1], client_data))
  19. link.sendall('服务器已经收到你的信息'.encode())
  20. link.close()
  21. ip_port = ('127.0.0.1', 9999)
  22. sk = socket.socket() # 创建套接字
  23. sk.bind(ip_port) # 绑定服务地址
  24. sk.listen(5) # 监听连接请求
  25. print('启动socket服务,等待客户端连接...')
  26. while True: # 一个死循环,不断的接受客户端发来的连接请求
  27. conn, address = sk.accept() # 等待连接,此处自动阻塞
  28. # 每当有新的连接过来,自动创建一个新的线程,
  29. # 并将连接对象和访问者的ip信息作为参数传递给线程的执行函数
  30. t = threading.Thread(target=link_handler, args=(conn, address))
  31. t.start()

启动这个多线程服务器,然后多运行几个客户端,可以很明显地看到,服务器能够同时与多个客户端通信,基本达到我们的目的。

UDP编程:
相对TCP编程,UDP编程就简单多了,当然可靠性和安全性也差很多。由于UDP没有握手和挥手的过程,因此accept()和connect()方法都不需要。下面是一个简单的例子:

  1. # 服务端
  2. import socket
  3. ip_port = ('127.0.0.1', 9999)
  4. sk = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, 0)
  5. sk.bind(ip_port)
  6. while True:
  7. data = sk.recv(1024).strip().decode()
  8. print(data)
  9. if data == "exit":
  10. print("客户端主动断开连接!")
  11. break
  12. sk.close()
  13. # 客户端
  14. import socket
  15. ip_port = ('127.0.0.1', 9999)
  16. sk = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, 0)
  17. while True:
  18. inp = input('发送的消息:').strip()
  19. sk.sendto(inp.encode(), ip_port)
  20. if inp == 'exit':
  21. break
  22. sk.close()

Python:socket编程教程的更多相关文章

  1. Python——Socket 编程教程

    这是用来快速学习 Python Socket 套接字编程的指南和教程.Python 的 Socket 编程跟 C 语言很像. Python 官方关于 Socket 的函数请看 http://docs. ...

  2. Python Socket 编程——聊天室示例程序

    上一篇 我们学习了简单的 Python TCP Socket 编程,通过分别写服务端和客户端的代码了解基本的 Python Socket 编程模型.本文再通过一个例子来加强一下对 Socket 编程的 ...

  3. python/socket编程之粘包

    python/socket编程之粘包 粘包 只有TCP有粘包现象,UDP永远不会粘包. 首先需要掌握一个socket收发消息的原理 发送端可以是1k,1k的发送数据而接受端的应用程序可以2k,2k的提 ...

  4. PYTHON SOCKET编程简介

    原文地址: PYTHON SOCKET编程详细介绍   Python 提供了两个基本的 socket 模块. 第一个是 Socket,它提供了标准的 BSD Sockets API. 第二个是 Soc ...

  5. python socket编程笔记

    用python实现一个简单的socket网络聊天通讯 (Linux --py2.7平台与windows--py3.6平台) 人生苦短之我用Python篇(socket编程) python之路 sock ...

  6. [Python_7] Python Socket 编程

    0. 说明 Python Socket 编程 1. TCP 协议 [TCP Server] 通过 netstat -ano 查看端口是否开启 # -*-coding:utf-8-*- "&q ...

  7. Python Socket 编程示例 Echo Server

    简评:我们已经从「Python Socket 编程概览」了解了 socket API 的概述以及客户端和服务器的通信方式,接下来让我们创建第一个客户端和服务器,我们将从一个简单的实现开始,服务器将简单 ...

  8. Python Socket 编程——聊天室演示样例程序

    上一篇 我们学习了简单的 Python TCP Socket 编程,通过分别写服务端和client的代码了解主要的 Python Socket 编程模型.本文再通过一个样例来加强一下对 Socket ...

  9. python socket编程入门(编写server实例)+send 与sendall的区别与使用方法

    python 编写server的步骤: 1. 第一步是创建socket对象.调用socket构造函数.如: socket = socket.socket( family, type ) family参 ...

  10. 第九章:Python高级编程-Python socket编程

    第九章:Python高级编程-Python socket编程 Python3高级核心技术97讲 笔记 9.1 弄懂HTTP.Socket.TCP这几个概念 Socket为我们封装好了协议 9.2 cl ...

随机推荐

  1. jsp第二周作业

    1.p39 实验2 显示当前时间,并输出上午(0-12)好,下午好(13-17),晚上好(18-23) <%@ page language="java" import=&qu ...

  2. windwos 下编译 qsqlibase 驱动(firebird 和 interbase)

    编译环境:mingw-w64 使用qtcreator打开ibase.pro,ibase.pro位置例如:R:\qt-everywhere-opensource-src-4.8.5\src\plugin ...

  3. SpringCloudAlibaba微服务docker容器打包和部署示例实战

    概述 我们使用前面<SpringCloudAlibaba注册中心与配置中心之利器Nacos实战与源码分析(中)>的两个微服务示例,分别是库存微服务和订单微服务,基于Nacos注册中心和配置 ...

  4. 2.1 安装Linux系统对硬件有什么要求?

    很多初学者在安装 Linux 系统时,都对自己的电脑配置存在质疑,担心其是否能够满足安装 Linux 的要求.本节就从 CPU.内存.硬盘.显卡等这些方面,详细介绍一下安装 Linux 系统的最低配置 ...

  5. 1.10 Linux桌面环境(桌面系统)大比拼[附带优缺点

    早期的 Linux 系统都是不带界面的,只能通过命令来管理,比如运行程序.编辑文档.删除文件等.所以,要想熟练使用 Linux,就必须记忆很多命令. 后来随着 Windows 的普及,计算机界面变得越 ...

  6. Flask01 第一个flask项目

    参考地址:https://github.com/miguelgrinberg/microblog/tree/v0.1 flask环境[苹果M1] 添加虚拟环境 python3 -m venv venv ...

  7. CSS 不规则的轮廓-outline

    大家好,我是半夏,一个刚刚开始写文的沙雕程序员.如果喜欢我的文章,可以关注 点赞 加我微信:frontendpicker,一起学习交流前端,成为更优秀的工程师-关注公众号:搞前端的半夏,了解更多前端知 ...

  8. 技术管理进阶——技术Leader如何拒绝业务方?

    原创不易,求分享.求一键三连 前段时间,有个粉丝在群里问了一个问题: 今天对接一个业务团队,要我帮他导数据,这种工作又臭又烦又没成长,而且边界模糊谁做都可以,我很想拒绝他,但又怕引起对方不满,大家有什 ...

  9. 详细剖析pyecharts大屏的Page函数配置文件:chart_config.json

    目录 一.问题背景 二.揭开json文件神秘面纱 三.巧用json文件 四.关于Table图表 五.同步讲解视频 5.1 讲解json的视频 5.2 讲解全流程大屏的视频 5.3 讲解全流程大屏的文章 ...

  10. 每天一个 HTTP 状态码 203

    203 Non-Authoritative Information 203 Non-Authoritative Information 'Non-Authoritative Informative' ...