一。基本语法

127.0.0.1     是本地回环地址

客户端                                                                                                                                                                          服务端

import socket                                                                                                                                                               import socket

client=socket.socket()                                                                                                                                                  server=socket.socket()         #买手机
ip_port=('127.0.0.1',8088)                                                                                                                                            ip_port=('127.0.0.1',8088)

client.connect(ip_port)   #连接的是一个元组,所以提前写好需要输入的IP和port                                                        server.bind(ip_port)             #插电话卡  注意括号内是一个小元组,避免出错,先将Ip_port先写在外面

                                                   server.listen(5)                    #监听状态   5是半连接池

                                                  conn,addr=server.accept()   #建立通信,已完成三次握手

client.secd(b'hello boy!')                                                   data=conn.recv (1024)        #   和客户端对照者写,move right   必须是一个输入,一个接受,否则就会出现双方都在输入/输出状态,就会出现阻塞现象

                                  print(data)

data=client.recv(1024)                                         conn.send(b'hihihihihi')                                       

print(data)                                              conn.close()

client.close()    #一次通信结束                                     server.close()

二。通信循环

上面我们已经可以实现两个计算机之间的相互通信,但是只是一次通信,如果要多次通信,就得多次输入,我们前面学过的可以多次输入的有什么?while循环

客户端                                                                                                                                                                          服务端

import socket                                                                                                                                                               import socket

client=socket.socket()                                                                                                                                                  server=socket.socket()         #买手机
ip_port=('127.0.0.1',8088)                                                                                                                                            ip_port=('127.0.0.1',8088)

client.connect(ip_port)   #连接的是一个元组,所以提前写好需要输入的IP和port                                                        server.bind(ip_port)             #插电话卡  注意括号内是一个小元组,避免出错,先将Ip_port先写在外面

                                                   server.listen(5)                    #监听状态   5是半连接池

                                                  conn,addr=server.accept()   #建立通信,已完成三次握手

while True:                                             while True:

  client.send(b'hello boy!')                                                     data=conn.recv (1024)

                                      print(data)

  data=client.recv(1024)                                           conn.send(b'hihihihihi')                                       

  print(data)                                              

                                                   conn.close()

client.close()    #一次通信结束                                     server.close()

三。链接循环

通信循环也已经实现了两台计算机之间的多次信息交流,但是发现只能一次服务一个客户端,但是服务端的特点是24小时不间断的提供服务,并且是提供给多个用户,地址也是不变的,那么如何实现提供多个服务给用户呢?链接循环走起来!

客户端                                                                                                                                                                          服务端

import socket                                                                                                                                                               import socket

client=socket.socket()                                                                                                                                                  server=socket.socket()         #买手机
ip_port=('127.0.0.1',8088)                                                                                                                                            ip_port=('127.0.0.1',8088)

client.connect(ip_port)   #连接的是一个元组,所以提前写好需要输入的IP和port                                                        server.bind(ip_port)             #插电话卡  注意括号内是一个小元组,避免出错,先将Ip_port先写在外面

                                                   server.listen(5)                    #监听状态   5是半连接池

                                              while True:   #这里就可以实现多个客户服务,所以得将建立连接信息放到第一个while里面     我们发现最多只可以打开6个客户端,一旦超过就报错

                                                   这是因为半连接池是5,就相当于只提供了5个凳子,先服务第一个用户,外面可以由5个人在 等,但是再来一个就报错!

                                                  conn,addr=server.accept()   #建立通信,已完成三次握手

while True:                                             while True:

  client.send(b'hello boy!')                                                     data=conn.recv (1024)

                                      print(data)

  data=client.recv(1024)                                           conn.send(b'hihihihihi')                                       

  print(data)                                              

                                                   conn.close()

client.close()    #一次通信结束                                     server.close()

四。异常处理

实际生活中:

1,用户提前中断了通道,会发现服务端直接报错,所以要对这个进行异常捕获

2.网络信号不好导致的问题

3.tcp协议是流的传输,输入信息不可以是空

客户端                                                                                                                                                                          服务端

import socket                                                                                                                                                               import socket

client=socket.socket()                                                                                                                                                  server=socket.socket()         #买手机
ip_port=('127.0.0.1',8088)                                                                                                                                            ip_port=('127.0.0.1',8088)

client.connect(ip_port)   #连接的是一个元组,所以提前写好需要输入的IP和port                                                        server.bind(ip_port)             #插电话卡  注意括号内是一个小元组,避免出错,先将Ip_port先写在外面

                                                   server.listen(5)                    #监听状态   5是半连接池

                                              while True:

                                                  conn,addr=server.accept()   #建立通信,已完成三次握手

while True: 

  msg=input('>>>:').encode('utf-8') 

  if len(msg)==0:continue                                        while True:

                                                     try:

  client.send(msg)                                                          data=conn.recv (1024)

                                                        if len(data)==0:break   #针对mac 和Linux系统,需要自己再加一步

                                        print(data)

  data=client.recv(1024)                                             conn.send(b'hihihihihi')                                       

  print(data)                                               except ConnectionRaseError:break

                                                   conn.close()

client.close()    #一次通信结束                                     server.close()

五。粘包问题

发现当自己输入的是task list之类的东西时,然后再次输入dir但是还是接收的是task list的信息,就是粘包,两个数据粘在了一起,解决方式

1.将recv的值改大,但是不是根本性的解决方式,因为你不知道用户传入的东西是多大,所以不推荐

2.将我们要传的东西先打包成固定大小,对方接受以后解包,看到大小,然后再根据大小来接受我们要传的东西(看下面总结)

总结:

发送消息端:

1.先发报头    2.在发字典(序列化成字符串)       3.再发你的真实数据

接收消息端:

1.先收4个长度的报头   2.解包拿到字典数据长度    3.接收字典(反序列化)获取字典里面的所有信息         4.接收真实数据

用到的模块分别是struck(pack,unpack),subprocess(标准输出stdout和错误流stderr)  json(序列化dumps和反序列化loads)   以及socket

客户端

import socket
import json
import struct
client=socket.socket()
ip_port=('127.0.0.1',8099)
client.connect(ip_port) while True:
msg=input('>>>:').strip().encode('utf-8')
if len(msg)==0:continue
client.send(msg)
head=client.recv(4) #head就是4
#对这个报头进行解包,获取真实数据的长度
head_len=struct.unpack('i',head)[0]
head_dic=json.loads(client.recv(head_len).decode('utf-8')) #反序列化
print(head_dic) total_size=head_dic['len'] #一定要由索引0
# unpack拿出来的是一个小元组
print(total_size) #如果发送内容过大,怎么做,循环接收值 recv_size=0
res=b''
while recv_size<total_size: #对需要的数据进行循环接受
data=client.recv(1024)
res+=data
recv_size+=len(data) #len(data)真实收到的数据,所以是data,不是1024
print(res.decode('gbk')) 服务端:
#服务端给用户端发送一个字典的内容
import socket
import struct
import json
import subprocess server=socket.socket() ip_port=('127.0.0.1',8099) server.bind(ip_port) server.listen(5) while True: conn,addr=server.accept() while True:
try:
data=conn.recv(1024)
if len(data)==0:break
print(data)
order=subprocess.Popen(data.decode('utf-8'),
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
) stdout=order.stdout.read()
stderr=order.stderr.read()
#传过来的真实长度
print(len(stderr+stdout))
#传字典
head_dic = {
'file_name': 'cls.txt',
'len': len(stdout + stderr)
}
#字典序列化
head_bytes=json.dumps(head_dic).encode('utf-8') #制作报头
head=struct.pack('i',len(head_bytes)) #将需要发送给客户端的打包成4个字节 conn.send(head) #head=4想拿到一些描述,传个字典 conn.send(head_bytes)
conn.send(stderr+stdout)
except ConnectionResetError:break

socket基本语法和粘包的更多相关文章

  1. day8---多线程socket 编程,tcp粘包处理

    复习下socket 编程的步骤: 服务端:   1 声明socket 实例 server = socket.socket()  #括号里不写  默认地址簇使用AF_INET  即 IPv4       ...

  2. c# Socket通讯中关于粘包,半包的处理,加分割符

    using System; using System.Collections.Generic; using System.Text; using System.Net.Sockets; using S ...

  3. python socket网络编程之粘包问题详解

    一,粘包问题详情 1,只有TCP有粘包现象,UDP永远不会粘包 你的程序实际上无权直接操作网卡的,你操作网卡都是通过操作系统给用户程序暴露出来的接口,那每次你的程序要给远程发数据时,其实是先把数据从用 ...

  4. Python开发【socket篇】解决粘包

    客户端 import os import json import struct import socket sk = socket.socket() sk.connect(('127.0.0.1',8 ...

  5. 11.1、socket连接中的粘包、精确传输问题

    粘包: 发生原因: 当调用send的时候,数据并不是即时发给客户端的.而是放到了系统的socket发送缓冲区里,等缓冲区满了.或者数据等待超时了,数据才会发送,所以有时候发送太快的话,前一份数据还没有 ...

  6. 6.2 socket 流协议与粘包

    TCP IP协议是流协议,对上层协议来讲是没有边界的,主机A发送两个消息M1和M2,如下图所示: 主机A发送了M1和M2,主机B在接收时有4种情况: 1.先收了M1,又收了M2 2.M1.M2一起收到 ...

  7. day08 多线程socket 编程,tcp粘包处理

    复习下socket 编程的步骤: 服务端:   1 声明socket 实例 server = socket.socket()  #括号里不写  默认地址簇使用AF_INET  即 IPv4       ...

  8. socket基于TCP(粘包现象和处理)

    目录 6socket套接字 7基于TCP协议的socket简单的网络通信 AF_UNIX AF_INET(应用最广泛的一个) 报错类型 单一 链接+循环通信 远程命令 9.tcp 实例:远程执行命令 ...

  9. python笔记8 socket(TCP) subprocess模块 粘包现象 struct模块 基于UDP的套接字协议

    socket 基于tcp协议socket 服务端 import socket phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 买 ...

随机推荐

  1. python 常用模块介绍

    1.定义 模块:用来从逻辑上组织python代码(变量.函数.类,逻辑),本质就是.py结尾的python文件(文件名:test.py,对应的模块名:test). 包:用来从逻辑上组织模块的,本质就是 ...

  2. Python【map、reduce、filter】内置函数使用说明

    题记 介绍下Python 中 map,reduce,和filter 内置函数的方法 一:map map(...) map(function, sequence[, sequence, ...]) -& ...

  3. 基于物理的渲染——间接光照

    在前面的文章中我们已经给出了基于物理的渲染方程: 并介绍了直接光照的实现.然而在自然界中,一个物体不会单独存在,光源会照射到其他的物体上,反射的光会有一部分反射到物体上.为了模拟这种环境光照的形式,我 ...

  4. 查漏补缺:C++STL简述(容器部分)

    STL:是Standard Template Library的简称,中文译为标准模板库,是由惠普实验室开发的一系列软件的统称,现为C++的一部分,可分为容器(containers).迭代器(itera ...

  5. Dart 运行速度测评与比较

    引言 Dart 是一门优秀的跨平台语言,尽管生态方面略有欠缺,但无疑作为一门编程语言来说,Dart 是很优美,很健壮的,同时也引入了一些先进的编程范式,值得去学习. 测试内容 现在,我们就来测评一下D ...

  6. 初识Arduino

    Arduino是一款便捷灵活.方便上手的开源电子原型平台.包含硬件(各种型号的Arduino板)和软件(Arduino IDE).由一个欧洲开发团队于2005年冬季开发.其成员包括Massimo Ba ...

  7. 压力测试(四)-Mysql数据库压测实操

    1.Jmeter压测实战之JDBC request压测Mysql讲解 简介:讲解jdbc压测mysql相关准备工作,jar包添加,配置讲解 1.Thread Group -> add -> ...

  8. JZOJ 5326. LCA 的统计 (Standard IO)

    5326. LCA 的统计 (Standard IO) Time Limits: 1000 ms Memory Limits: 131072 KB Description Input Output S ...

  9. python之三元表达式,列表|字典推导式,函数对象

    #### 三元表达式: 就是if....else...的语法糖 # -- 1) 只能解决if...else...结构,其他if分支结构都不管 # -- 2)一个分支提供一个结果: 如果一个分支提供了多 ...

  10. 编码的来源于格式简介ANSI、GBK、GB2312、UTF-8、GB18030和 UNICODE

    编码一直是让新手头疼的问题,特别是 GBK.GB2312.UTF-8 这三个比较常见的网页编码的区别,更是让许多新手晕头转向,怎么解释也解释不清楚.但是编码又是那么重要,特别在网页这一块.如果你打出来 ...