一。基本语法

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. Maven和Ant简介以及两者的区别

    Maven 一.Maven简介 Maven是基于项目对象模型(POM),可以通过一小段描述信息来管理项目的构建,报告和文档的软件项目管理工具. 目前,绝大多数开发人员都把 Ant 当作 Java 编程 ...

  2. Mongdb创建 连接过程

    在bin目录下启动后 Show dbs 显示库,库里有内容才会显示库名称 Use admin 切换库 没有的默认创建 show users显示用户信息 Show collections显示表名 db. ...

  3. Hexo博客maupassant主题添加Google Adsense广告

    自从在 Github Page 落户以后,很长一段时间使用的是极简且有点艺术范儿的 fexo 主题,而不是大名鼎鼎的 next 主题.后来偶然发现了符合我审美的Hexo博客 maupassant 主题 ...

  4. Js对于数组去重提高效率一些心得

    最近在找工作,好几次面试都问过数组去重的问题.虽然问的都不一样,但是核心思想是没有变的. 第一种是比较常规的方法 思路: 构建一个新的数组存放结果 for循环中每次从原数组中取出一个元素,用这个元素循 ...

  5. CSS——NO.7(布局模型)

    */ * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:text.cpp * 作者:常轩 * 微信公众号:Worldhe ...

  6. C++走向远洋——34(友元函数,成员函数和一般函数的区别)

    */ * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:youyuan.cpp * 作者:常轩 * 微信公众号:Worl ...

  7. django之学习前的准备

    一.配置环境 Windows 10操作系统 Python安装配置教程参考:https://www.cnblogs.com/huangbiquan/p/7784533.html 安装Python虚拟环境 ...

  8. SpringBoot2整合Redis缓存

    遵循SpringBoot三板斧 第一步加依赖 <!-- Redis --> <dependency> <groupId>org.springframework.bo ...

  9. OpenCV读一张图片并显示

    Java 版本: JavaCV 用OpenCV读一张图片并显示.只需将程序运行时的截图回复.如何安装配置创建项目编写OpenCV代码,可参考何东健课件和源代码或其他资源. package com.gi ...

  10. 正式学习MVC 01

    1.新建项目 点击创建新项目,选择ASP.NET web应用程序,对项目进行命名后点击创建. 截图如下: 取消勾选HTTPS配置 可选择空 + mvc 或直接选定MVC 2.目录结构分析 1) App ...