soket的使用笔记(个人随意笔记)

socket网络服务

socket就是IP地址加端口定位到唯一一台机器的唯一软件

套节字分两大类型

一个是文件类型套节字家族
AF_UNIX
一个是网络套节字家族
AF_INET

tcp协议:

如何定义socket服务端(模拟通信):
import socket
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.bind((‘127.0.0.1‘,8080))
phone.listen(5)
while True:#连接循环
    conn,addr=phone.accept()
    print(‘电话线路是‘,conn)
    print(‘客户端的手机号是‘,addr)
    while True:#通信循环
        try:
            data=conn.recv(1024)
            if not data:break#在linx中因为系统无法对客户端的断开抛出异常所以会一直接收空的状态所以需要针对linx进行额外判断
            print(‘客户端发来的消息是‘,data)
            conn.send(data.upper())
        except Exception as e:
            break
    print(‘客户端已经断开‘)
    conn.close()
phpne.close()

定义socket客户端:
import socket
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.connect((‘127.0.0.1‘,8080))
while True:
    try:
        myinput=input(‘>>‘)
        if not myinput:continue
        phone.send(myinput.encode(‘utf8‘))
        data=phone.recv(1024)
        print(data)
    except Exception as e:
        print(e)
        break
phone.close()

当重启服务端的时候有可能会遇上time_wait状态,这个是由于你的服务端仍然存在四次挥手的time_wait状态在占用地址(如果不懂,请深入研究1.tcp三次握手,四次挥手 2.syn洪水攻击 3.服务器高并发情况下会有大量的time_wait状态的优化方法)

解决方法:
phone=socket(AF_INET,SOCK_STREAM)
phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) #就是它,在bind前加
phone.bind((‘127.0.0.1‘,8080))

如何解决粘包的问题:

如何不让多个数据粘一块发出去呢?
在发包的时候先发送数据长度,知道长度之后就知道一次要收到多少数据,就可以避免粘包了。

封装报头:
固定长度
发送数据的时候要包含对将要发送数据的详细信息
如何将数据长度打包?
引入模块
import struct
res=struct.pack(‘i‘,数据)
struct.unpack(‘i‘,res)
(数据,)#元祖形式
struct.unpack(‘i‘,res)[0]

客户端定制包头:
import socket,struct,json
import subprocess
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)

如何让服务器重用ip端口号避免冲突?
phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) #就是它,在bind前加

phone.bind((‘127.0.0.1‘,8080))#服务器绑定ip加端口号
phone.listen(5)#开启监听

while True:#链接循环
    conn,addr=phone.accept()
    while True:#通讯循环
        cmd=conn.recv(1024)
        if not cmd:break
        print(‘cmd: %s‘ %cmd)

res=subprocess.Popen(cmd.decode(‘utf-8‘),
                             shell=True,
                             stdout=subprocess.PIPE,
                             stderr=subprocess.PIPE)
        err=res.stderr.read()
        print(err)
        if err:
            back_msg=err
        else:
            back_msg=res.stdout.read()

conn.send(struct.pack(‘i‘,len(back_msg))) #先发back_msg的长度
        conn.sendall(back_msg) #在发真实的内容

conn.close()
phone.close()

客户端接收报头:

import socket,struct,json
import subprocess
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) #就是它,在bind前加

phone.bind((‘127.0.0.1‘,8080))

phone.listen(5)

while True:
    conn,addr=phone.accept()
    while True:
        cmd=conn.recv(1024)
        if not cmd:break
        print(‘cmd: %s‘ %cmd)

res=subprocess.Popen(cmd.decode(‘utf-8‘),
                             shell=True,
                             stdout=subprocess.PIPE,
                             stderr=subprocess.PIPE)
        err=res.stderr.read()
        print(err)
        if err:
            back_msg=err
        else:
            back_msg=res.stdout.read()

conn.send(struct.pack(‘i‘,len(back_msg))) #先发back_msg的长度
        conn.sendall(back_msg) #在发真实的内容

conn.close()

服务端的特点是:
 一直运行提供服务(链接循环),(基于一个链接的通信循环)

高并发:
之前学过的服务端客户端都是一对一的,这种方式一次服务器只能访问一个人,其余的挂起状态 
而有一个模块可以实现并发的形式
socketserver模块

#高并发服务端,可以接入多个客户端
import socketserver

class FTPserver(socketserver.BaseRequestHandler):#通讯
 def handle(self):
  conn=self.request
  while 1:
   data=conn.recv(1024)
   conn.send(....)

if __name__==‘__main__‘:
 obj=socketserver.ThreadingTCPServer((‘127.0.0.1‘,8080),FTPserver)
 obj.sever_forever()#链接循环
 
#以上代码中每当进来一个客户端链接都会实例化一个通讯对象,通讯对象类中是一个通讯循环

#udp的使用也是如此区别不大

 
udp协议:

服务端:
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 绑定端口:
s.bind((‘127.0.0.1‘, 9999))
#因为udp是无链接,所以不用监听接口,因为没有监听所以也没有阻塞

print(‘Bind UDP on 9999...‘)
while True:
    # 接收数据:
    data, addr = s.recvfrom(1024)
    print(‘Received from %s:%s.‘ % addr)
    s.sendto(b‘Hello, %s!‘ % data, addr)

客户端:
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
for data in [b‘Michael‘, b‘Tracy‘, b‘Sarah‘]:
    # 发送数据:
    s.sendto(data, (‘127.0.0.1‘, 9999))
    # 接收数据:
    print(s.recv(1024).decode(‘utf-8‘))
s.close()

时间: 2024-10-13 21:49:47

soket的使用笔记(个人随意笔记)的相关文章

Kettle笔记: Transformation 笔记

触发器表输入:select a.*,b.*,0 as ztflag from exchange_trigger a left join MAEA_NET_BIZ_BASEINFO b on (a.keyvalue=b.id) where a.flag=0 and a.tablename='MAEA_NET_BIZ_BASEINFO' 附件处理脚本: //Script here var byte_FILEDATA = null; if(FILEDATA != null && FILEDATA

[读书笔记]C#学习笔记八:StringBuilder与String详解及参数传递问题剖析

前言 上次在公司开会时有同事分享windebug的知识, 拿的是string字符串Concat拼接 然后用while(true){}死循环的Demo来讲解.其中有提及string操作大量字符串效率低下的问题, 刚好自己之前也看过类似的问题, 于是便拿出来记录一下.本文内容: 参数传递问题剖析, string与stringbuilder详解 1,参数传递问题剖析 对于C#中的参数传递,根据参数的类型可以分为四类: 值类型参数的按值传递 引用类型参数的按值传递 值类型参数的按引用传递 引用类型参数的

[算法学习笔记]直接插入排序笔记

直接插入排序概念: 带排元素放在elem[0...n-1]中,初始化时,elem[0]自成1个有序区,无序区为elem[1...n-1],从i=1起,到i=n-1,依次将elem[i]插入有序区[0...n-1]中 直接插入排序算法步骤: 1.在当前有序区域R[1,i-1]中查找R[i]的正确插入位置K(1<=K<=i-1) 2.将R[K,i-1]中的记录均向后移动 3.移动后腾出K位置,插入R[i] (最坏)时间复杂度:O(n^2) 空间复杂度:O(1) /// <summary>

contiki-main.c 中的process系列函数学习笔记 &lt;contiki学习笔记之六&gt;

说明:本文依然依赖于 contiki/platform/native/contiki-main.c 文件. ------------------------------------------------------------------------------------------------------------------------------------- 根据上一个笔记里面添加的printf()语句的打印信息提示,hello world 打印是在执行了 1 autostart_

scala笔记和akka笔记

非阻塞的程序 应该保障的一些特性 : 等待无关性wait-free:能确保每次的调用在有限的步数之内完成,不管其他调用的步骤有多少.杀掉几个线程 锁无关性lock-free:执行这段程序的某些线程会被延迟,但必须确保至少有一个线程能持续步骤到执行完毕.这一点需防止可能出现的饿死,就是说防止某个线程永远被延迟. 阻碍阻塞无关性obstruction-free:有个时间点,在这个点之后非阻塞方法独立的在有限次步骤内执行完毕 锁无关的程序一定是阻碍无关的,反之不一定. 乐观并行控制法是障碍阻塞无关的,

【SAP学习笔记】随意记

*BEx Query Designer 1.只能开发,不能在Excel中分析报表的结果,但便于控制权限,可在portal中展示. 2.Filter面板中的Characteristic Restrictions和Default Values:前者是特性限制,这个区域所做的特性的限制会对整个报表的结果集生效:后者是默认值,也就是报表的初始值,可以在导航时改变.前者限制条件后,一直作用于整个报表,除非重新输入条件,否则在报表结果中无法更改:后者限制条件后,可以重新调整Default Value的值来改

angular js随意笔记

<!DOCTYPE html> <html> <head> <meta charset="utf-8"><script src="js/jquery-1.11.2.min.js"></script> <script src="http://apps.bdimg.com/libs/angular.js/1.4.6/angular.min.js"></scrip

[读书笔记]C#学习笔记一: .Net Framwork

前言: 一次偶然的机会  在园子里看到@Learning hard 出版的一本书: <<C#学习笔记>>, 然后买来 一直到现在读完, 感觉很不错, 适合入门, 书中内容是从C#1.0 到5.0. 很全面也很细致. 下面就来分享一下这本书中自己感觉需要记录的一些东西. 这里先贴上@Learning hard本人在博客园的主页: http://www.cnblogs.com/zhili/     以及本书中的一些知识点: http://www.cnblogs.com/zhili/ca

[读书笔记]C#学习笔记六: C#3.0Lambda表达式及Linq解析

前言 最早使用到Lambda表达式是因为一个需求:如果一个数组是:int[] s = new int[]{1,3,5,9,14,16,22};例如只想要这个数组中小于15的元素然后重新组装成一个数组或者直接让s返回一个新数组该怎么截取? 最开始的想法就是将这个s遍历一遍然后判断下再来重新组装成新的数组.好麻烦是不是? 于是便百度到了一个叫做Lambda的东西, 所以用了之后效果如下: 1 class Program 2 { 3 static void Main(string[] args) 4