socket简介

1. 什么是socket ?

socket(简称 套接字) 是进程间通信的一种方式,它与其他进程间通信的一个主要不同是:
它能实现不同主机间的进程间通信,我们网络上各种各样的服务大多都是基于 Socket 来完成通信的
例如我们每天浏览网页、QQ 聊天、收发 email 等等
2.注意:
  • 所谓进程指的是:运行的程序以及运行时用到的资源这个整体称之为进程
  • 所谓进程间通信指的是:运行的程序之间的数据共享

3. 创建socket

在 Python 中 使用socket 模块的函数 socket 就可以完成:
import socket
socket.socket(AddressFamily, Type)

说明:

函数 socket.socket 创建一个 socket,该函数带有两个参数:
  • Address Family:可以选择 AF_INET(用于 Internet 进程间通信) 或者 AF_UNIX(用于同一台机器进程间通信),实际工作中常用AF_INET
  • Type:套接字类型,可以是 SOCK_STREAM(流式套接字,主要用于 TCP 协议)或者 SOCK_DGRAM(数据报套接字,主要用于 UDP 协议)
创建一个udp socket(udp套接字)
 
import socket

# 创建udp的套接字
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # ...这里是使用套接字的功能(省略)... # 不用的时候,关闭套接字
s.close()
创建一个tcp socket(tcp套接字)
import socket

# 创建tcp的套接字
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # ...这里是使用套接字的功能(省略)... # 不用的时候,关闭套接字
s.close()
一、 网络—udp通信:
 
udP通信模型如图:
 

1. udp网络程序-发送数据:

  1. 创建客户端套接字
  2. 发送/接收数据
  3. 关闭套接字
示例代码如下:
#coding=utf-8

from socket import *

# 1. 创建udp套接字
udp_socket = socket(AF_INET, SOCK_DGRAM) # 2. 准备接收方的地址# '192.168.133.1'表示目的ip地址# 8080表示目的端口
dest_addr = ('192.168.133.1', 8080) # 注意 是元组,ip是字符串,端口是数字 # 3. 从键盘获取数据
send_data = input("请输入要发送的数据:") # 4. 发送数据到指定的电脑上的指定程序中
udp_socket.sendto(send_data.encode('utf-8'), dest_addr) # 5. 关闭套接字
udp_socket.close()
 
运行网络调试助手:

 2. udp网络程序-发送、接收数据
#coding=utf-8

from socket import *

# 1. 创建udp套接字
udp_socket = socket(AF_INET, SOCK_DGRAM) # 2. 准备接收方的地址
dest_addr = ('192.168.133.1', 8080) # 3. 从键盘获取数据
send_data = input("请输入要发送的数据:") # 4. 发送数据到指定的电脑上
udp_socket.sendto(send_data.encode('utf-8'), dest_addr) # 5. 等待接收对方发送的数据
recv_data = udp_socket.recvfrom(1024) # 1024表示本次接收的最大字节数 # 6. 显示对方发送的数据# 接收到的数据recv_data是一个元组# 第1个元素是对方发送的数据
# 第2个元素是对方的ip和端口
print(recv_data[0].decode('gbk'))
print(recv_data[1]) # 7. 关闭套接字
udp_socket.close()

运行网络调试助手:

 
在pycharm中运行程序:
 
 

应用:udp聊天器

说明

  • 在一个电脑中编写1个程序,有2个功能
  • 1.获取键盘数据,并将其发送给对方
  • 2.接收数据并显示
  • 并且功能数据进行选择以上的2个功能调用
 代码如下:

import socket

def send_msg(udp_socket):
"""获取键盘数据,并将其发送给对方"""
  # 1. 从键盘输入数据
  msg = input("请输入要发送的数据:")
  # 2. 输入对方的ip地址
  dest_ip = input("请输入对方的ip地址:")
  # 3. 输入对方的port
  dest_port = int(input("请输入对方的port:"))
  # 4. 发送数据
  udp_socket.sendto(msg.encode("utf-8"), (dest_ip, dest_port)) def recv_msg(udp_socket):
"""接收数据并显示"""
  # 1. 接收数据
  recv_msg = udp_socket.recvfrom(1024)
  # 2. 解码
  recv_ip = recv_msg[1]
  recv_msg = recv_msg[0].decode("utf-8")
  # 3. 显示接收到的数据
  print(">>>%s:%s" % (str(recv_ip), recv_msg)) def main():
  # 1. 创建套接字
  udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  # 2. 绑定本地信息
  udp_socket.bind(("", 7890))
  while True:
    # 3. 选择功能
    print("="*30)
    print("1:发送消息")
    print("2:接收消息")
    print("="*30)
    op_num = input("请输入要操作的功能序号:")     # 4. 根据选择调用相应的函数
    if op_num == "":
      send_msg(udp_socket)
    elif op_num == "":
      recv_msg(udp_socket)
    else:
      print("输入有误,请重新输入...") if __name__ == "__main__":
  main()
二、 网络—tcp通信:
 
TCP通信模型如图:

tcp客户端构建流程:

1.创建socket  
2. 建立连接 connect  
3. 发送 send  
4. 接收recv 
示例代码:
from socket import *

# 创建socket
tcp_client_socket = socket(AF_INET, SOCK_STREAM) # 目的信息
server_ip = input("请输入服务器ip:")
server_port = int(input("请输入服务器port:")) # 链接服务器
tcp_client_socket.connect((server_ip, server_port)) # 提示用户输入数据
send_data = input("请输入要发送的数据:") tcp_client_socket.send(send_data.encode("gbk")) # 接收对方发送过来的数据,最大接收1024个字节
recvData = tcp_client_socket.recv(1024)
print('接收到的数据为:', recvData.decode('gbk')) # 关闭套接字
tcp_client_socket.close()

运行网络调试助手:

在pycharm中运行程序:

 
tcp服务器构建流程:
  1. socket创建一个套接字
  2. bind绑定ip和port
  3. listen使套接字变为可以被动链接
  4. accept等待客户端的链接
  5. recv/send接收发送数据
示例代码:
from socket import *

# 创建socket
tcp_server_socket = socket(AF_INET, SOCK_STREAM) # 本地信息
address = ('', 7788) # 绑定
tcp_server_socket.bind(address) # 使用socket创建的套接字默认的属性是主动的,使用listen将其变为被动的,这样就可以接收别人的链接了
tcp_server_socket.listen(128) # 如果有新的客户端来链接服务器,那么就产生一个新的套接字专门为这个客户端服务
# client_socket用来为这个客户端服务# tcp_server_socket就可以省下来专门等待其他新客户端的链接
client_socket, clientAddr = tcp_server_socket.accept() # 接收对方发送过来的数据
recv_data = client_socket.recv(1024) # 接收1024个字节
print('接收到的数据为:', recv_data.decode('gbk')) # 发送一些数据到客户端
client_socket.send("thank you !".encode('gbk')) # 关闭为这个客户端服务的套接字,只要关闭了,就意味着为不能再为这个客户端服务了,如果还需要服务,
# 只能再次重新连接
client_socket.close()

运行流程:

<1>tcp服务器:

<2>网络调试助手:

tcp注意点:

  1. tcp服务器一般情况下都需要绑定,否则客户端找不到这个服务器
  2. tcp客户端一般不绑定,因为是主动链接服务器,所以只要确定好服务器的ip、port等信息就好,本地客户端可以随机
  3. tcp服务器中通过listen可以将socket创建出来的主动套接字变为被动的,这是做tcp服务器时必须要做的
  4. 当客户端需要链接服务器时,就需要使用connect进行链接,udp是不需要链接的而是直接发送,但是tcp必须先链接,只有链接成功才能通信
  5. 当一个tcp客户端连接服务器时,服务器端会有1个新的套接字,这个套接字用来标记这个客户端,单独为这个客户端服务
  6. listen后的套接字是被动套接字,用来接收新的客户端的链接请求的,而accept返回的新套接字是标记这个新客户端的
  7. 关闭listen后的套接字意味着被动套接字关闭了,会导致新的客户端不能够链接服务器,但是之前已经链接成功的客户端正常通信。
  8. 关闭accept返回的套接字意味着这个客户端已经服务完毕
  9. 当客户端的套接字调用close后,服务器端会recv解堵塞,并且返回的长度为0,因此服务器可以通过返回数据的长度来区别客户端是否已经下线
  10. 先运行server的代码,再运行client的代码。

案例:文件下载器

服务器 参考代码如下:

from socket import *
import sys def get_file_content(file_name):
"""获取文件的内容"""
  try:
    with open(file_name, "rb") as f:
    content = f.read()
    return content
  except:
    print("没有下载的文件:%s" % file_name) def main():   if len(sys.argv) != 2:
    print("请按照如下方式运行:python3 xxx.py 7890")
    return
  else:
    # 运行方式为python3 xxx.py 7890
    port = int(sys.argv[1])   # 创建socket
  tcp_server_socket = socket(AF_INET, SOCK_STREAM)
  # 本地信息
  address = ('', port)
  # 绑定本地信息
  tcp_server_socket.bind(address)
  # 将主动套接字变为被动套接字
  tcp_server_socket.listen(128)   while True:
    # 等待客户端的链接,即为这个客户端发送文件
    client_socket, clientAddr = tcp_server_socket.accept()
    # 接收对方发送过来的数据
    recv_data = client_socket.recv(1024) # 接收1024个字节
    file_name = recv_data.decode("utf-8")
    print("对方请求下载的文件名为:%s" % file_name)
    file_content = get_file_content(file_name)
    # 发送文件的数据给客户端
    # 因为获取打开文件时是以rb方式打开,所以file_content中的数据已经是二进制的格式,因此不需要encode编码
    if file_content:
      client_socket.send(file_content)
      # 关闭这个套接字
      client_socket.close()   # 关闭监听套接字
  tcp_server_socket.close() if __name__ == "__main__":
  main()

客户端 参考代码如下:

from socket import *

def main():

  # 创建socket
  tcp_client_socket = socket(AF_INET, SOCK_STREAM)   # 目的信息
  server_ip = input("请输入服务器ip:")
  server_port = int(input("请输入服务器port:"))   # 链接服务器
  tcp_client_socket.connect((server_ip, server_port))   # 输入需要下载的文件名
  file_name = input("请输入要下载的文件名:")   # 发送文件下载请求
  tcp_client_socket.send(file_name.encode("utf-8"))   # 接收对方发送过来的数据,最大接收1024个字节(1K)
  recv_data = tcp_client_socket.recv(1024)
  # print('接收到的数据为:', recv_data.decode('utf-8'))
  # 如果接收到数据再创建文件,否则不创建
  if recv_data:
    with open("[接收]"+file_name, "wb") as f:
    f.write(recv_data)   # 关闭套接字
  tcp_client_socket.close() if __name__ == "__main__":
  main()

python 套接字Socket详解的更多相关文章

  1. day29 python 套接字socket TCP udp 形式发送信息的区别

    我们经常把socket翻译为套接字,socket是在应用层和传输层之间的一个抽象层,它把TCP/IP层复杂的操作抽象为几个简单的接口供应用层调用已实现进程在网络中通信. socket起源于UNIX,在 ...

  2. python中的tcp示例详解

    python中的tcp示例详解  目录 TCP简介 TCP介绍 TCP特点 TCP与UDP的不同点 udp通信模型 tcp客户端 tcp服务器 tcp注意点   TCP简介   TCP介绍 TCP协议 ...

  3. Python套接字编程(1)——socket模块与套接字编程

    在Python网络编程系列,我们主要学习以下内容: 1. socket模块与基本套接字编程 2. socket模块的其他网络编程功能 3. SocketServer模块与简单并发服务器 4. 异步编程 ...

  4. python套接字解决tcp粘包问题

    python套接字解决tcp粘包问题 目录 什么是粘包 演示粘包现象 解决粘包 实际应用 什么是粘包 首先只有tcp有粘包现象,udp没有粘包 socket收发消息的原理 发送端可以是一K一K地发送数 ...

  5. 面向对象之套接字(socket)和黏包

    一丶套接字(socket) tcp是基于链接的,必须先启动服务端,然后再启动客户端去链接服务端 基于UDP协议的socket server端: import socket udp_sk = socke ...

  6. 网络编程 套接字socket TCP UDP

    网络编程与套接字 网络编程 网络编程是什么: ​ 网络通常指的是计算机中的互联网,是由多台计算机通过网线或其他媒介相互链接组成的 ​ 编写基于网络的应用程序的过程序称之为网络编程. 网络编程最主要的工 ...

  7. 网络协议学习笔记(五)套接字Socket

    概述 前面学习网络知识的时候写过一篇关于套接字的随笔见<JAVA SOCKET 详解>,现在本人正在系统的学习网络知识,现在除了温故知新之外,在详细的学习记录一下套接字的知识. Socke ...

  8. python套接字基本使用

    socket socket通常也称作"套接字",用于描述IP地址和端口,应用程序通常通过"套接字"向网络发出请求或者应答网络请求,可以认为是一种计算机网络的数据 ...

  9. Python安装、配置图文详解(转载)

    Python安装.配置图文详解 目录: 一. Python简介 二. 安装python 1. 在windows下安装 2. 在Linux下安装 三. 在windows下配置python集成开发环境(I ...

随机推荐

  1. How to add Facebook’s Customer Chat Plugin to your website

    How to add Facebook’s Customer Chat Plugin to your website By Gerardo Salandra  Do you need a live c ...

  2. UPDATE SELECT OUTPUT

    -- 定义临时表变量,用于 output into 使用 DECLARE @VarOrderStatus table ( OrderNo nvarchar(50) NULL) -- update 表U ...

  3. 【转】转载一篇优质的讲解epoll模型的文章

    从事服务端开发,少不了要接触网络编程.Epoll 作为 Linux 下高性能网络服务器的必备技术至关重要,Nginx.Redis.Skynet 和大部分游戏服务器都使用到这一多路复用技术. Epoll ...

  4. Reactor系列(七)flatMap映射

    #java##reactor##flatMap# 视频讲解: https://www.bilibili.com/video/av79582009/ FluxMonoTestCase.java pack ...

  5. 洛谷P3381 最小费用最大流模板

    https://www.luogu.org/problem/P3381 题目描述 如题,给出一个网络图,以及其源点和汇点,每条边已知其最大流量和单位流量费用,求出其网络最大流和在最大流情况下的最小费用 ...

  6. [Cometoj#4 B]奇偶性_打表

    奇偶性 题目链接:https://cometoj.com/contest/39/problem/B?problem_id=1577 数据范围:略. 题解: 因为$f$的构造原因,很容易找到规律. 进而 ...

  7. Linux 下面安装 nginx 以及进行TCP反向代理、负载均衡的过程

    1. 下载安装nginx 注意 因为stream 并不是 nginx自带的module  所以需要 在安装是 通过 --with 的方式增加上. 下载必要的程序包 # openssl wget htt ...

  8. PL/SQL developer 11.0注册码

    PL/SQL developer 11.0注册码:product key:lhsw85g33x4p7leqk63hy8q28ffxzzvbxlserial No:193085password:xs37 ...

  9. 【LOJ】#2239. 「CQOI2014」危桥

    LOJ#2239. 「CQOI2014」危桥 就是先把每条边正着连一条容量为2的边,反着连一条容量为2的边 显然如果只有一个人走的话,答案就是一个源点往起点连一条容量为次数×2的边,终点往汇点连一个次 ...

  10. cmd寻找tomcat的命令和删除进程的命令

    netstat -ano | findstr 8080taskkill -f -pid 端口 idea 异常关闭,无法启动Tomcat提示Error running ‘server_web’: Una ...