socket是操作系统中I/O系统延伸部分,支持TCP和UDP等网络通信协议,它使计算机之间(或其本身)的进程通信称为可能。socket中的socket()函数、recv()函数和send()函数,相当于文件操作中的open()函数、read()函数、write()函数。因此,soket使得操作系统能够以文件描述符的方式对网络数据进行操作。

1、socket中udp通信

  服务端:

import socket
udpSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# ''表示自己电脑的任何一个ip(无线和有限同时连接或者电脑有不同的网卡(桥接),会有多个ip).
# 绑定端口:写的是自己的ip和固定的端口,一般是写在sever端
bindAddr = ('', 9001)
udpSocket.bind(bindAddr)
recvData = udpSocket.recvfrom(1024)
# print(recvData)
print(recvData[0].decode('gbk'))
udpSocket.close()
# recvData的格式:(data, ('ip', 端口)).它是一个元组,前面是数据,后面是一个包含ip和端口的元组.

  客户端:

import socket
# upd链接
# SOCK_DGRAM:数据报套接字,主要用于UDP协议
udpSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 关闭防火墙
# 同一网段(局域网)下,主机的ip地址和端口号.
sendAddr = ('127.0.0.1', 9001)
# sendData = bytes(input('请输入要发送的数据:'), 'gbk')
sendData = input('请输入要发送的数据:').encode('gbk')
# 使用udp发送数据,每一次发送都需要写上接收方的ip地址和端口号
udpSocket.sendto(sendData, sendAddr)
# udpSocket.sendto(b'hahahaha', ('192.168.10.247', 8080))
udpSocket.close()

2、socket中的TCP通信

  服务端:

import socket
tcpServer = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcpServer.bind(('', 8899))
tcpServer.listen(5)
# tcp的三次握手,写进了这一句话当中
tcpClient, addr = tcpServer.accept()
# tcpServer.accept(),不需要写ip,可以接收多个客户端的。但事先要绑定端口和接入的客户端的数量
# client 表示接入的新的客户端
# clientInfo 表示接入的新的客户端的ip和端口port
recvData = tcpClient.recv(1024)
print('%s: %s' % (str(addr), recvData.decode('gbk')))
sendData = input("请输入返回数据: ")
tcpClient.send(sendData.encode("gbk"))
# tcp的四次握手,写进了这一句话
tcpClient.close()
tcpServer.close()
# tcpServer.accept():等待客户端的接入,自带堵塞功能:即必须接入客户端,然后往下执行
# tcpClient.recv(1024): 也是堵塞,不输入数据就一直等待,不往下执行.
# tcpServer创建了两个套接字,一个是Server,另一个是tcpClient.Server负责监听接入的Client,再为其创建专门的tcpClient进行通信.

  客户端:

import socket
tcpClient = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serverAddr = ('127.0.0.1', 8899)
# tcp的三次握手,写进了这一句话
tcpClient.connect(serverAddr)
sendData = input('请输入要发送的数据:')
tcpClient.send(sendData.encode('gbk'))
recvData = tcpClient.recv(1024)
print('接收到的数据为:%s' % recvData.decode('gbk'))
tcpClient.close()
# 为什么用send而不是sendto?因为tcp连接是事先链接好(只需连接一次),以后只管发数据就ok了。
# 而udp必须用sendto,是发一次数据,连接一次。每次发送必须要指定对方的ip和port。
# 相同的道理,在tcpServer端,要写recv,而不是recvfrom来接收数据

3、socket开启循环

  服务端:

import socket
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(('127.0.0.1', 9003))
server.listen(5)
while True:
serverThisClient, addr = server.accept()
while True:
recvData = serverThisClient.recv(1024)
if len(recvData) > 1:
print('recv: %s' % recvData.decode('utf-8'))
sendData = input('send: ')
serverThisClient.send(sendData.encode('utf-8'))
else:
print('再见!')
break
serverThisClient.close()
server.close()

  客户端:

import socket
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(('127.0.0.1', 9003))
while True:
data = input("send:")
client.send(data.encode("utf-8"))
recv = client.recv(1024)
print("recv: %s" % recv.decode("utf-8"))
client.close()

4、socket多线程

  socket是自带阻塞的。一次只能接收和处理一个链接。如果一次接收多个连接,可以用多线程的方式实现。改写上面服务器的写法,客户端保持不变(可以启动多个client看看效果)。

from threading import Thread
import socket
class Connect(object):
  """connect就是一个链接"""
def __init__(self, conn, addr):
self.conn = conn # 本次链接的conn
self.addr = addr # 本次链接的ip地址和端口
self.bsize = 1024
self.before()
try:
self.handle()
except:
raise socket.SO_ERROR
self.after() def handle(self):
try:
while True:
recvData = self.conn.recv(self.bsize)
print("recv: %s." % recvData.decode("utf-8"))
sendData = input("send: ")
self.conn.send(sendData.encode("utf-8"))
except:
self.conn.close() def before(self):
print("Connected from: %s." % self.addr[0]) def after(self):
print("Closed from %s." % self.addr[0]) def main():
tcpSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcpSocket.bind(('', 9003))
tcpSocket.listen(5)
while True:
conn, addr = tcpSocket.accept()
Thread(target=Connect, args=(conn, addr)).start()
tcpSocket.close() if __name__ == '__main__':
main()

5、使用自带的socketServer模块实现socket多线程

  上面已经实现了多线程的socket连接。python提供了socketServer来实现功能更全面的封装。对上面的服务端用socketServer进行重写。

import socketserver
class Server(socketserver.BaseRequestHandler):
def handle(self):
while True:
recvData = self.request.recv(1024)
print("recv: %s." % recvData.decode("utf-8"))
sendData = input("send: ")
self.request.send(sendData.encode("utf-8"))
if __name__ == '__main__':
server = socketserver.ThreadingTCPServer(("", 9003), Server)
server.serve_forever()

6、socketserver实现文件传输

  服务端:

  (文件地址:https://files.cnblogs.com/files/kuaizifeng/Python%E9%87%8D%E8%A6%81%E7%9A%84%E7%AC%AC%E4%B8%89%E6%96%B9%E5%BA%93.pdf.zip)

import socketserver, struct
class MyServer(socketserver.BaseRequestHandler):
def handle(self):
f = open("Python重要的第三方库.pdf.zip", mode="ab")
size = self.request.recv(4) # 只接收4个字节
size = struct.unpack('i', size)[0] # struct模块将python中的数据类型转换成C中的字节。第一次发数据大小,是int类型(struct用i表示),它在C中占4个字节
print(size) # 如果recv接收不是4个字节,则会报错(粘包)
length = 0
while True:
data = self.request.recv(1024)
f.write(data)
length += len(data)
if len(data) < 1024:
f.close()
break
if length == size:
print("over.")
else:
print("error.")
if __name__ == '__main__':
server = socketserver.ThreadingTCPServer(("", 9009), MyServer)
server.serve_forever()

  客户端:

import socket, struct, os

client = socket.socket()
client.connect(("localhost", 9009)) filepath= os.path.dirname(os.path.dirname(__file__)) # 定位这个文件路径
file = os.path.join(filepath, "Python重要的第三方库.pdf.zip")
f = open(file, mode="rb")
count = 0
size = os.path.getsize(file)
size = struct.pack('i', size)
client.send(size)
print("size: {}.".format(size))
while True:
data = f.read(1024)
client.send(data)
count += 1
if len(data) < 1024:
break
print("send: {}.".format(count))
client.close()

python(十三):网络编程之socket与socketserver的更多相关文章

  1. Python自动化运维之15、网络编程之socket、socketserver、select、twisted

    一.TCP/IP相关知识 TCP/UDP提供进程地址,两个协议互不干扰的独自的协议       TCP :Transmission Control Protocol 传输控制协议,面向连接的协议,通信 ...

  2. Python 之网络编程之socket(2)黏包现象和socketserver并发

    一:黏包 ###tcp协议在发送数据时,会出现黏包现象.     (1)数据粘包是因为在客户端/服务器端都会有一个数据缓冲区,     缓冲区用来临时保存数据,为了保证能够完整的接收到数据,因此缓冲区 ...

  3. Python 之网络编程之socket(1)TCP 方式与UDP方式

    一:socket介绍 网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket. 建立网络通信连接至少要一对端口号(socket).socket本质是编程接口(API) ...

  4. Python 之网络编程之socket(3)hashlib模块

     hashlib模块 #hashlib 这个模块是一堆加密算法的集合体,哈希算法的加密方式不止一种 httpswww.cmd5.com md5解密 # 应用场景在需要效验功能时使用     用户密码的 ...

  5. 网络编程之socket

    网络编程之socket socket:在网络编程中的一个基本组件,也称套接字. 一个套接字就是socket模块中的socket类的一个实例. 套接字包括两个: 服务器套接字和客户机套接字 套接字的实例 ...

  6. 网络编程之Socket & ServerSocket

    网络编程之Socket & ServerSocket Socket:网络套接字,网络插座,建立网络通信连接至少要一对端口号(socket).socket本质是编程接口(API),对TCP/IP ...

  7. GO语言的进阶之路-网络编程之socket

    GO语言的进阶之路-网络编程之socket 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.什么是socket; 在说socket之前,我们要对两个概念要有所了解,就是IP和端口 ...

  8. [深入浅出Cocoa]iOS网络编程之Socket

    http://blog.csdn.net/kesalin/article/details/8798039 版权声明:本文为博主原创文章,未经博主允许不得转载.   目录(?)[+]   [深入浅出Co ...

  9. 网络编程之Socket代码实例

    网络编程之Socket代码实例 一.基本Socket例子 Server端: # Echo server program import socket HOST = '' # Symbolic name ...

随机推荐

  1. 【转】学习Python的19个资源

    原文链接:[译]学习Python编程的19个资源 用Python编写代码一点都不难,事实上它一直被赞誉为最容易学的编程语言.如果你准备学习web开发, Python是一个不错的开始,甚至想做游戏的话, ...

  2. 在 Ubuntu 里如何下载、安装和配置 Plank Dock

    一个众所周知的事实就是,Linux 是一个用户可以高度自定义的系统,有很多选项可以选择 —— 作为操作系统,有各种各样的发行版,而对于单个发行版来说,又有很多桌面环境可以选择.与其他操作系统的用户一样 ...

  3. Pycharm-professional-2017.2.3破解安装

    初次接触Python,大神推荐使用PyCharm IDE工具,作为小白初生牛犊不怕虎,上手就来最新版的,这也许不是最好的选择,但在以后慢慢琢磨深入之后,会选择适合自己的版本,现参考把安装过程分享出来. ...

  4. day20 project+查看新闻列表 + 点赞 + 图片验证码 + 评论和多级评论 + 后台管理 + webSocket + kindEditor

    Day20回顾: 1. 请求生命周期 2. 中间件 md = [ "file_path.classname" ] process_request[可有可无] process_res ...

  5. springboot拦截器注入service为空

    一般都是因为除了在拦截器之外,还需要在拦截器的配置类中,注册拦截器时没有使用spring的bean,而是使用了new创建bean造成的. @Configuration public class Web ...

  6. linux中安装eclipse--CnetOS6.5

    01.去官网下载指定的eclipse安装包 02.使用xftp把下载的eclipse安装包放入到linux系统的指定位置03.到指定的目录下!使用命令解压下载的文件tar -zxvf 文件名称04. ...

  7. springboot--常用注解--@configration、@Bean

    @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Component public @inter ...

  8. 【html】META http-equiv 大全

    meta是html语言head区的一个辅助性标签.几乎所有的网页里,我们可以看到类似下面这段的html代码: <head><meta http-equiv="content ...

  9. iOS笔记之内存泄露

    非ARC中,对于被autorelease的对象,Leak工具也会视其为泄露,自己知道没问题就行. 今天遇到一个bug,App在XCode调试时没有问题,但在真机安装,退出,再进入时,会出现闪退. 用X ...

  10. window环境下创建Flask项目需要安装常见模块命令

    安装Flask环境 pip install flask==0.10.1 使用命令行操作 pip install flask-script 创建表单 pip install flask-wtf 操作数据 ...