Date: 2019-06-10

Author: Sun

1. Python TCP通信实现

socket()函数

Python 中,我们用 socket()函数来创建套接字,语法格式如下:

socket.socket([family[, type[, proto]]])

参数

  • family: 套接字家族可以使AF_UNIX或者AF_INET

  • type: 套接字类型可以根据是面向连接的还是非连接分为SOCK_STREAMSOCK_DGRAM

  • protocol: 一般不填默认为0.

注:

​ socket只能发送字节类型的数据 所以在发送时要将发送的数据通过str.encode() 转为字节类型,接收时在通过str.decode()转为字符串。

Socket 对象(内建)方法

函数 描述
服务器端套接字
s.bind() 绑定地址(host,port)到套接字, 在AF_INET下,以元组(host,port)的形式表示地址。
s.listen() 开始TCP监听。backlog指定在拒绝连接之前,操作系统可以挂起的最大连接数量。该值至少为1,大部分应用程序设为5就可以了。
s.accept() 被动接受TCP客户端连接,(阻塞式)等待连接的到来
客户端套接字
s.connect() 主动初始化TCP服务器连接,。一般address的格式为元组(hostname,port),如果连接出错,返回socket.error错误。
s.connect_ex() connect()函数的扩展版本,出错时返回出错码,而不是抛出异常
公共用途的套接字函数
s.recv() 接收TCP数据,数据以字符串形式返回,bufsize指定要接收的最大数据量。flag提供有关消息的其他信息,通常可以忽略。
s.send() 发送TCP数据,将string中的数据发送到连接的套接字。返回值是要发送的字节数量,该数量可能小于string的字节大小。
s.sendall() 完整发送TCP数据,完整发送TCP数据。将string中的数据发送到连接的套接字,但在返回之前会尝试发送所有数据。成功返回None,失败则抛出异常。
s.recvfrom() 接收UDP数据,与recv()类似,但返回值是(data,address)。其中data是包含接收数据的字符串,address是发送数据的套接字地址。
s.sendto() 发送UDP数据,将数据发送到套接字,address是形式为(ipaddr,port)的元组,指定远程地址。返回值是发送的字节数。
s.close() 关闭套接字
s.getpeername() 返回连接套接字的远程地址。返回值通常是元组(ipaddr,port)。
s.getsockname() 返回套接字自己的地址。通常是一个元组(ipaddr,port)
s.setsockopt(level,optname,value) 设置给定套接字选项的值。
s.getsockopt(level,optname[.buflen]) 返回套接字选项的值。
s.settimeout(timeout) 设置套接字操作的超时期,timeout是一个浮点数,单位是秒。值为None表示没有超时期。一般,超时期应该在刚创建套接字时设置,因为它们可能用于连接的操作(如connect())
s.gettimeout() 返回当前超时期的值,单位是秒,如果没有设置超时期,则返回None。
s.fileno() 返回套接字的文件描述符。
s.setblocking(flag) 如果flag为0,则将套接字设为非阻塞模式,否则将套接字设为阻塞模式(默认值)。非阻塞模式下,如果调用recv()没有发现任何数据,或send()调用无法立即发送数据,那么将引起socket.error异常。
s.makefile() 创建一个与该套接字相关连的文件

socket异常

Exception 解释
socket.error 由Socket相关错误引发
socket.herror 由地址相关错误引发
socket.gaierror 由地址相关错误,如getaddrinfo()或getnameinfo()引发
socket.timeout 当socket出现超时时引发。超时时间由settimeout()提前设定

交互过程

TCP服务端:

1 创建套接字,绑定套接字到本地IP与端口

s = socket.socket(socket.AF_INET,socket.SOCK_STREAM),s.bind()

2 开始监听连接

s.listen()

3 进入循环,不断接受客户端的连接请求

s.accept()

4 然后接收传来的数据,并发送给对方数据

s.recv() , s.send()

5 传输完毕后,关闭套接字

s.close()

TCP客户端:

1 创建套接字,连接远端地址

socket.socket(socket.AF_INET,socket.SOCK_STREAM) , s.connect()

2 连接后发送数据和接收数据

s.send(), s.recv()

3 传输完毕后,关闭套接字

s.close()

2. TCP协议的Python实现

服务器端:

# -*- coding: utf-8 -*-
__author__ = 'sun'
__date__ = '2019/6/10 0:13' from socket import *
from time import ctime
HOST = ''
PORT = 21567
BUFSIZ = 1024
ADDR = (HOST, PORT)
tcpSerSock = socket(AF_INET, SOCK_STREAM) ##创建服务器TCP套接字
tcpSerSock.bind(ADDR)
tcpSerSock.listen(5)
while True:
print('waiting for connection...')
tcpCliSock, addr = tcpSerSock.accept() ##等待客户端连接
print('...connected from:', addr)
while True:
data = tcpCliSock.recv(BUFSIZ) ##监听客户端是否发送消息
print(data)
if not data:
break
tcpCliSock.send(data)
tcpCliSock.close() tcpSerSock.close()

客户端代码:

# -*- coding: utf-8 -*-
__author__ = 'sun'
__date__ = '2019/6/10 9:30' from socket import * HOST = 'localhost'
PORT = 21567
BUFSIZ = 1024
ADDR = (HOST, PORT)
tcpCliSock = socket(AF_INET, SOCK_STREAM) ##创建客户端TCP套接字
tcpCliSock.connect(ADDR) ##连接服务器
while True:
data = input('> ')
if not data:
break
tcpCliSock.send(data.encode(encoding='utf8'))
data = tcpCliSock.recv(BUFSIZ) ##监听客户端发送消息
if not data:
break
print(data)
tcpCliSock.close()

3. Python UDP通信实现

UDP则是面向无连接的协议。

使用UDP协议时,不需要建立连接,只需要知道对方的IP地址和端口号,就可以直接发数据包。但是,能不能到达就不知道了。

虽然用UDP传输数据不可靠,但它的优点是和TCP比,速度快,对于不要求可靠到达的数据,就可以使用UDP协议。

服务器端代码:

import socket

'''
使用UDP协议时,不需要建立连接,只需要知道对方的IP地址和端口号,就可以直接发数据包。但是,能不能到达就不知道了。 虽然用UDP传输数据不可靠,但它的优点是和TCP比,速度快,对于不要求可靠到达的数据,就可以使用UDP协议。 我们来看看如何通过UDP协议传输数据。和TCP类似,使用UDP的通信双方也分为客户端和服务器。服务器首先需要绑定端口
绑定端口和TCP一样,但是不需要调用listen()方法,而是直接接收来自任何客户端的数据
'''
# ipv4 SOCK_DGRAM指定了这个Socket的类型是UDP
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 绑定 客户端口和地址:
s.bind(('127.0.0.1', 9999))
print('Bind UDP on 9999...')
while True:
# 接收数据 自动阻塞 等待客户端请求:
data, addr = s.recvfrom(1024)
print('Received from %s:%s.' % addr)
s.sendto('Hello, %s!' % data, addr)
# recvfrom()方法返回数据和客户端的地址与端口,这样,服务器收到数据后,直接调用sendto()就可以把数据用UDP发给客户端。

客户端代码

import socket

'''
客户端使用UDP时,首先仍然创建基于UDP的Socket,然后,不需要调用connect(),直接通过sendto()给服务器发数据:
'''
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) for data in ['python', 'java', 'c']:
# 发送数据:
s.sendto(data, ('127.0.0.1', 9999))
# 接收数据:
print(s.recv(1024))
s.close()

最新文章

  1. 深入理解javascript函数定义与函数作用域
  2. LR测试登陆后进行的操作时 绕过登录
  3. (1)创建一个叫做机动车的类: 属性:车牌号(String),车速(int),载重量(double) 功能:加速(车速自增)、减速(车速自减)、修改车牌号,查询车的载重量。 编写两个构造方法:一个没有形参,在方法中将车牌号设置“XX1234”,速 度设置为100,载重量设置为100;另一个能为对象的所有属性赋值; (2)创建主类: 在主类中创建两个机动车对象。
  4. UVA 10294 等价类计数
  5. eclipse内存溢出报错:java.lang.OutOfMemoryError:Java heap space
  6. 【转】使用Memcached提高.NET应用程序的性能
  7. [C++程序设计]用指向数组的指针作函数参数
  8. img标签的方方面面
  9. IE6 png图片实现半透明的方法
  10. WCF技术剖析之十四:泛型数据契约和集合数据契约(下篇)
  11. 11.4.2 排序或合并文件(sort命令) - 51CTO.COM
  12. html中 iframe子页面 与父页面之间的方法调用 ;
  13. Unity中的万能对象池
  14. C语言中NULL的定义
  15. POJ 3294 出现在至少K个字符串中的子串
  16. Mac下Git安装及配置
  17. webpack 单独打包指定JS文件(CopyWebpackPlugin)
  18. RxJAVA notes
  19. Python---Models 模型
  20. flask 源码剖析

热门文章

  1. docker批量删除容器、镜像
  2. hibernate一对多和多对一配置
  3. nginx视频服务缓存方案设置指导
  4. PostgreSQL 安装配置 (亲测可用)
  5. WEBGL学习【三】颜色选择
  6. useradd常用参数介绍
  7. 简述JVM、JRE、JDK的关系及作用
  8. SpringBoot2整合activiti6环境搭建
  9. 工具-vscode使用
  10. BA-siemens-TX-IO模块照片