TCP : 可靠传输,不安全,UDP: 安全传输,不可靠

一台机器上有2^16-1=65535个端口(1-1024)保留自己开就1024往上

socket (套接字):也可以理解为它是一个管道,用于描述IP地址和端口

socket是一种特殊的文件:针对服务器端和客户端来 打开(建立链接),读(发送数据),写(接收数据)关闭的模式来实现信息的交换

一、socket函数

socket.socket(family,type[, protocol])   默认协议为TCP/IP

# socket.slcketpair([family,type[,proto]]]):

# socket.create_connection(address[,timeout[, source_address]])

参数说明:

1.family指定应用程序使用的通信协议的协议族

family参数
socket.AF_UNIX 只能单一的在Unix系统进行进程通信,一种本地的管道(socket)
socket.AF_INET IPv4 为TCP/IP协议的默认值,服务器之间的网络通信
socket.AF_INET6 IPv6

2.type创建套接字的类型

type参数
socket.SOCK_STREAM  流式socket,用于TCP时选用
socket.SOCK_DGRAM 数据报式socket,用于UDP时选用

socket.SOCK_RAM

原始套接字,普通的套接字无法处理ICMP  , IGMP 等网络报文,而SOCK_RAM可以;其次,SOCK_RAM也可以处理特殊的IPv4报文;此外,利用原始套接字,可以通过IP_HDRINCT套接字选项由用户构造IP头。

socket.SOCK_RDM

是一种可靠的UDP形式,即可保证交付数据但不保证顺序 ,SOCK_RAM用来提供对原始协议的低级访问,在需要某些特殊操作时使用,如发生ICMP报文,SOCK_RAM通常仅限于高级用户或管理员运行的程序使用.

3.protocol指明所要接收的协议类型,通常设置为0,系统就会根据地址格式和套接类别自动选择一个合适的协议

protocol参数

socket.IPPROTO_TAW

相当于protocol=255,此时socket只能用来发送IP包,而不能接收任何的数据,发送的数据需要自己填充IP包头,并且自己计算校验和

socket.IPPROTO_IP

相当于protocol=0,此时用于接收任何的IP数据包,其中校验和和协议分析由系统完成

二、socket内建方法

服务器端套接字

sk.bind()

将套接字绑定地址,address地址的格式取决于地址簇,在AF_INET下,以(host.port )的形式表示地址

sk.listen(backlog)

开始监听传入连接,backlog指定在拒绝连接之前,可以挂起的最大连接数量,等待排队的最多排几个,如:backlog等于5,表示内核已经接到了连接要求,但服务器还没有调用accept进行处理的连接个数,这个值不能无限大,因为要在内核中维护连接队列。

sk.accept()

接受TCP客户连接并返回(conn,address),阻塞式等待连接其到来,其中conn是新的套接字对象,可以用来接受和发送数据,address 是客户端的地址。
客户端套接字
s.connect() 主动初始化TCP服务器连接,一般address的格式为元组(hostname,port),如果连接出错,则返回socket.error错误
s.connet_ex() 同上,不过,连接成功是返回0,连接失败是返回错误码,不会抛出异常
公共用途套接字

sk.recv(bufsize[,flag])

接受套接字的数据。数据以字符串的形式返回,bufsize指定最多可接收的数据(一般为8192),flag提供有关消息的其他信息,通常可以忽略
sk.recvform() 与recv()类似,多用于接受UDP数据,返回值为(data,address),其中data是包含接受数据的字符串,address是发送数据的套接字地址
sk.send() 发送套接字数据,将string中的数据发送到连接的套接字,返回值是要发送的字节数量,该数据可能小于string的字节大小
sk.sendall() 完整发送TCP数据,将string中的数据发送到连接的套接字,但返回之前会尝试一次性发送,就是不断的调用send,发送成功返回None,失败则抛出异常
sk.sendto() 发送UDP数据,将数据发送到套接字,address的形式是(ipaddr,port)的元组,指定远程地址,返回值是发送的字节数
sk.close() 关闭套接字
sk.getpeername() 返回连接套接字的远程地址,返回值通常是元组(ipaddr,port)
sk.getsockname() 返回套接字自己的地址,通常是一个元组(ipaddr,port)
sk.setsockopt() 设置给定套接字选项的值
sk.getsockopt() 返回条件字选项的值
sk.settimeout(timeout)  设置套接字操作的超时期,timeout是一个浮点数,单位为秒,值为None表示没有超时期,一般,超时期应该在刚创建套接字时设置,因为它们可能用于连接的操作(如connect())
sk.gettimeout() 返回当前超时期的值,如果没有设置超时期,则返回为None
sk.fileno() 返回套接字的文件描述符
sk.setblocking(flag) 是否阻塞(默认为True),如果设置False或0(即非堵塞模式),那么accept和recv时一旦无数据,则报错
sk.makefile() 创建一个与该套接字相关联的文件

实例一:你说一句,我说一句

import socket
ip_port = ("127.0.0.1", 1313) sk = socket.socket()
sk.bind(ip_port) # 创建端口
sk.listen(5) # 监听多少个 while True:
print("等待消息。。")
conn,addr = sk.accept() # 生成地址和一个实例线程
while True:
try: # 如果客户端端口,没有消息了,抓取异常,跳出循环
client_data = conn.recv(1024) # 接收消息
print(str(client_data, "utf8"))
except Exception:
print("over")
break server_input = input(">>").strip() # 发送消息
conn.sendall(bytes(server_input,"utf8"))
conn.close()

服务器端

import socket

ip_port = ("127.0.0.1",1313)

sk = socket.socket()      # 实例化
sk.connect(ip_port) # 连接端口
while True:
client_data = input(">>").strip()
sk.sendall(bytes(client_data,"utf8")) # 发送消息
server_data = sk.recv(1024) # 接收消息
print(str(server_data,"utf8"))
sk.close()

客户端

实例二:在Linux上Python3实现客户端发命令,服务器端把客户端命令实现,并发回客户端

#!/usr/bin/python
# -*- coding:utf-8 -*-
import socket
import subprocess
ip_port = ('127.0.0.1',9999)
sk = socket.socket()
sk.bind(ip_port)
sk.listen(5)
while True:
print('server waiting...')
conn,addr = sk.accept()
while True:
client_data = conn.recv(1024)
if not client_data:break # 如果没有客户端发来的消息则退出
print('recv cmd:',str(client_data,'utf8')) # 打印客户端发来了的消息
cmd = str(client_data, 'utf8').strip() cmd_call = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE) # 把客户发来的消息执行结果放在管道里 cmd_result = cmd_call.stdout.read() # 把 cmd 的执行结果读出来
if len(cmd_result) == 0: # 如果结果为 0
cmd_result = b'cmd execution has no output...'
ack_msg = bytes('CMD_RESULT_SIZE|%s' % len(cmd_result), 'utf8') # 文件名和长度发回客户端
conn.send(ack_msg)
client_ack = conn.recv(50) # 向客户端确认消息 (收),用来解决粘包
if client_ack.decode() == "yes":
conn.send(cmd_result) # 确认后,才向客户端发数据
conn.close()

服务器端

#!usr/bin/python3
# -*- coding:utf-8 -*-
import socket ip_port = ('127.0.0.1',9999)
sk = socket.socket()
sk.connect(ip_port) while True:
user_input = input('cmd:').strip()
if len(user_input) == 0:continue
if user_input =='q':break # 按q可以退出 sk.send(bytes(user_input,'utf8')) # 发消息 server_ack_msg = sk.recv(100) # 每次接收服务器端发来的消息最大长度
cmd_res_msg = str(server_ack_msg.decode()).split("|") # 去掉 | ,并转码
print('server response:',cmd_res_msg) # 打印 文件名,总长度
if cmd_res_msg[0] =="CMD_RESULT_SIZE": # 确定 文件名
cmd_res_size = int(cmd_res_msg[1]) # 确定文件长度
sk.send(b"yes") # 发回消息确认,解决粘包 res = '' # 保存 文件内容
received_size = 0
# (在服务器端和客户端中各有一个缓冲区,在一定的时间内客户端接收数据不够500,也会先进行收数据,其他的就下次再收)
while received_size < cmd_res_size: # 如果 文件内容,小于发来的长度
data = sk.recv(500) # 每次接收最大长度 为500 received_size += len(data) # 累加
res += str(data.decode())
else:
print(str(res))
print('---------------------')
sk.close()

客户端

客户端:

[root@localhost python_day2018_10_28]# python3 client_1.py
cmd:df
server response: ['CMD_RESULT_SIZE', '']
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/mapper/centos-root 18307072 2056032 16251040 12% /
devtmpfs 490096 0 490096 0% /dev
tmpfs 500664 0 500664 0% /dev/shm
tmpfs 500664 6956 493708 2% /run
tmpfs 500664 0 500664 0% /sys/fs/cgroup
/dev/sda1 508588 111880 396708 22% /boot
tmpfs 100136 0 100136 0% /run/user/0 ---------------------
cmd: 服务器端: [root@localhost python_day2018_10_28]# python3 server.py
server waiting...
recv cmd: df

result

Python_socket的更多相关文章

  1. Python_socket常见的方法、网络编程的安全注意事项、socketsever模块、浏览器中在一段时间记录用户的登录验证机制

    1.socket常见的方法 socket_常见方法_服务器端 import socket from socket import SOL_SOCKET,SO_REUSEADDR sk = socket. ...

  2. python_socket (套接字)

    socket是计算机网络通信的基本的技术之一.如今大多数基于网络的软件,如浏览器,即时通讯工具甚至是P2P下载都是基于Socket实现的. 网络上两个程序通过一个双向的通信连接实现数据的交换,这个连接 ...

  3. python_socket登陆验证_明文

    client.py import socket import struct sk=socket.socket() sk.connect(('127.0.0.1',9005)) while True: ...

  4. 使用 Python 进行 socket 编程

    本文主要参考 https://docs.python.org/3/howto/sockets.html . 本文只讨论 STREAME(比如 TCP) INET(比如 IPv4) socket. 在多 ...

  5. python开发之路目录

    Python 目录 基础 python入门 python数据类型.字符编码.文件处理 python函数基础 python函数进阶 python装饰器函数 python装饰器函数 python递归函数 ...

  6. python_18(Django基础)

    第1章 web框架的本质 1.1 socket 1.2 空格后面是主体内容 1.3 HTTP协议 1.3.1 响应流程 1.4 HTTP请求方法 1.5 HTTP工作原理 1.6 URL 1.7 HT ...

随机推荐

  1. you-get 2017-06-02

    可下载优酷土豆的1080p视频 修订版本 针对最近优酷土豆升级后无法下载的问题进行修改 需要安装 python3 和 ffmpeg http://pan.baidu.com/s/1c2hBCe0

  2. 6-CSS

    HTML Style Tags CSS stands for Cascading Style Sheets. CSS describes how HTML elements are to be dis ...

  3. MVC5访问SQL Server数据库

    参考: MVC5+EF6简单实例---以原有SQLServer数据库两表联合查询为例 1.新建MVC项目: 新建基于MVC5的项目,命名为PracticeProject 2.Models文件夹(右击) ...

  4. Node.js的那些坑——如何让异步并发方法同步顺序执行(for循环+异步操作)

    1 前言 nodejs的回调,有时候真的是让人又爱又恨的,当需要用for循环把数据依次存入数据库,但是如果使用正常的for循环,永远都是最后一次值的记录,根本不符合要求. 解决此方案有几种,例如闭包( ...

  5. JS读取.properties文件的方法

    假设有JavaScript文件叫做:readproperties.js,这个文件需要读取config.properties这个配置文件,步骤如下: 1.  下载插件jquery.i18n.proper ...

  6. 布思算法——Java实现

    前面一篇提到二进制队列实现了 N位二进制的补码,那么我们来实现布思算法. 关于BinaryQueue:https://www.cnblogs.com/XT-xutao/p/10050518.html ...

  7. 时间格式化 Date-formatDate

    //日期格式化 export function formatDate(date,fmt){ var o = { "M+":date.getMonth() + 1,//月份 &quo ...

  8. 处理数据库 Ora-00845: memory_traget not supported on this system 的错误

    问题出现情况:在数据库启动的时候:如果出现如下图的错误: 查看官方文档: 处理操作步骤: [oracle@localhost orcl]$ su - root Password: [root@loca ...

  9. 快速理解VirtualBox的四种网络连接方式

    VirtualBox中有4中网络连接方式: NAT Bridged Adapter Internal Host-only Adapter VMWare中有三种,其实他跟VMWare 的网络连接方式都是 ...

  10. Confluence 6 Oracle 连接问题解决

    如果 Confluence 提示没有 class 文件,你可能将你的 JDBC 驱动放置到了错误的文件夹. 下面的页面包含了一些你在使用 Oracle 数据库连接的时候可能会遇到的常见问题,请参考: ...