精华内容
下载资源
问答
  • wpe抓包、封包、发包制作图文教程
  • 好了,这样就完成了 抓包发包的过程。 抓包是个神奇的操作,手机端可以使用fiddler来抓。 接下来就是使用擅长的语言编写成软件了,易语言可以使用精易模块完成,java可以使用httpclient完成。 什么你说编码...

    预热:谷歌浏览器 或者火狐浏览器 (其他浏览器一样的原理 依葫芦画瓢)
    然后还要准备一个post 助手(只要能使用winhttp 等 协议进行post get等操作的工具) 我使用idea的 restClient 这里写图片描述;
    然后还要有一个编码转换工具,这个百度就好。
    ————————————————-开搞开搞。
    —————-这里我省略了QQ登入绑定电话号码,这个我就不多说了这两步要是教你我怕你入狱。(假装我会的样子哈哈)
    首先改浏览器的useragent,不然浏览器无法访问微信或者qq上面分享的链接
    修改教程:https://blog.csdn.net/qq_35189120/article/details/82559598
    修改以后开始分析浏览器在我们打开链接以后都干了什么。
    打开浏览器f12 netwrok 火狐点网络 勾起 缓存
    这里写图片描述
    看见这控制台的警告,太可怕了,为了防止我口袋的两块钱被人骗走我还是快点教完吧,
    首先我们看见载入浏览器的时候不停的发送数据,但我们的浏览器都已经抓住了(这就是抓包)
    随便拿一条分析一下 结构
    这里写图片描述
    这个没啥说的上面都写的这么清楚。我们在抓包的时候主要看 post和get操作类型可以点上面的xhr这里写图片描述
    这样就过滤掉静态文件了(css.js.png…..这些没啥用js倒是有点用但是本次不涉及)
    剩下的东西我们一条条分析,
    我们点响应看看有什么东西这里写图片描述
    看到这些东西了吗?都是好东西,里面有领取记录,以及其他信息,那么我们猜测这一条就是领取hb的数据,如何证明呢,打开post助手 我使用rest client ,把需要的参数帮过来,首先是地址,然后请求方法,接着是cookies(本教程粗略介绍这个,其实只要部分参数 ,还有就是有的不需要这个。 这个靠经验,靠尝试),然后是请求参数了,这个可以直接复制过来,是一个json格式的我们选择text发送。具体如下:
    这里写图片描述
    弄好以后点发送看响应:这里写图片描述
    对比一下浏览器的结果没错这就是我们要的东西,具体参数自己分析哈,这参数都没有变形一目了然是干嘛的。好了,这样就完成了 抓包发包的过程。
    抓包是个神奇的操作,手机端可以使用fiddler来抓。
    接下来就是使用擅长的语言编写成软件了,易语言可以使用精易模块完成,java可以使用httpclient完成。
    什么你说编码软件没用到,那是因为这条数据是没进行编码的,你看看cookies是不是发现有奇怪的符号,没错这种就是被编码了,具体什么编码自己尝试,多看几次就知道什么编码长什么样了。然后就是放一个半成品装B这里写图片描述

    展开全文
  • wpe抓包、封包、发包及外挂制作图文教程网上找到的,
  • 这款工具是用于拦截程序的发包和收包,非常的清楚。
  • JAVA并发包

    2020-12-31 11:51:42
    标题@JAVA并发包 欢迎使用Markdown编辑器 你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。 新的改变 我们对...

    标题@JAVA并发包

    JAVA并发包

    CopyOnWriteArrayList

    多线程操作List集合,要保证线程安全,就使用CopyOnWriteArrayList
    //定义线程类

    public class MyThread extends Thread {
    //    public static List<Integer> list = new ArrayList<>();//线程不安全的
        //改用:线程安全的List集合:
        public static CopyOnWriteArrayList<Integer> list = new CopyOnWriteArrayList<>();
    
        @Override
        public void run() {
            for (int i = 0; i < 10000; i++) {
                list.add(i);
            }
            System.out.println("添加完毕!");
        }
    }
    

    //测试类

    public class Demo {
        public static void main(String[] args) throws InterruptedException {
            MyThread t1 = new MyThread();
            MyThread t2 = new MyThread();
    
            t1.start();
            t2.start();
    
            Thread.sleep(1000);
    
            System.out.println("最终集合的长度:" + MyThread.list.size());
        }
    }
    

    //结果是正确的

    CopyOnWriteArraySet

    多线程操作set集合,保证线程安全,使用CopyOnWriteArraySet

    //线程类

    public class MyThread2 extends Thread {
        // 共享集合
        //static HashSet<Integer> set = new HashSet<>();// 线程不安全
        static CopyOnWriteArraySet<Integer> set = new CopyOnWriteArraySet<>();// 线程安全
    
        @Override
        public void run() {
            // 线程的任务:往集合中添加10000个元素
            for (int i = 0; i < 10000; i++) {
                set.add(i);
            }
            System.out.println("子线程执行完毕");
        }
    }
    
    

    //测试类

      public class Test2 {
          public static void main(String[] args) throws InterruptedException {
              // 需求: 多条线程操作同一个Set集合(往集合中添加10000个元素)
              new MyThread2().start();
              new MyThread2().start();
      
              // 为了保证以上2条线程都操作完毕
              Thread.sleep(2000);
      
              System.out.println("集合元素个数:"+ MyThread2.set.size());// 10000个
      
      
      
          }
      }
    

    ConcurrentHashMap

    多线程操作Map集合,要保证线程安全,就使用ConcurrentHashMap集合
    //线程类

    public class MyThread3 extends Thread {
        // 共享集合
        static ConcurrentHashMap<Integer,Integer> map = new ConcurrentHashMap<>();// 线程安全
    
        @Override
        public void run() {
            // 线程的任务:往集合中添加10000个键值对
            for (int i = 0; i < 10000; i++) {
                map.put(i,i);
            }
            System.out.println("子线程执行完毕");
        }
    }
    

    //测试类

    public class Test3 {
        public static void main(String[] args) throws InterruptedException {
            // 需求: 多条线程操作同一个Map集合(往集合中添加10000个键值对)
            new MyThread3().start();
            new MyThread3().start();
    
            // 为了保证以上2条线程都操作完毕
            Thread.sleep(2000);
    
            System.out.println("集合元素个数:"+ MyThread3.map.size());// 10000
    
    
        }
    }
    
    

    //HashTable效率低下原因

    public synchronized V put(K key, V value) 
    public synchronized V get(Object key)
    

    //HashTable容器使用synchronized来保证线程安全
    在这里插入图片描述
    // ConcurrentHashMap高效的原因
    在这里插入图片描述

    CountDownLatch

    CountDownLatch允许一个或多个线程等待其他线程完成操作
    //CountDownLatch构造方法:

    public CountDownLatch(int count)// 初始化一个指定计数器的CountDownLatch对象   1 
    

    //CountDownLatch重要方法:

    public void await() // 让当前线程等待
    public void countDown()	// 计数器进行减1
    

    //1). 制作线程1:

    public class MyRunnable1 implements Runnable {
        CountDownLatch cdl;
    
        public MyRunnable1(CountDownLatch cdl) {
            this.cdl = cdl;
        }
    
        @Override
        public void run() {
            System.out.println("A");
            // 暂停,等待线程2执行打印B,执行完回到这里来执行打印C
            try {
                cdl.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("C");// 打印C之前一定要去执行打印B
        }
    }
    
    

    //2). 制作线程2:

    public class MyRunnable2 implements Runnable {
    
        CountDownLatch cdl;
    
        public MyRunnable2(CountDownLatch cdl) {
            this.cdl = cdl;
        }
    
        @Override
        public void run() {
            System.out.println("B");
            // 计数器-1
            cdl.countDown();// 计数器的值为0
        }
    }
    
    

    //3).制作测试类:

    public class Test {
        public static void main(String[] args) throws InterruptedException {
            /*
                CountDownLatch:
                    作用: 允许一个或多个线程等待其他线程完成操作。
                    常用方法:
                        public CountDownLatch(int count)// 初始化一个指定计数器的CountDownLatch对象
                        public void await() throws InterruptedException// 让当前线程等待
                        public void countDown()	// 计数器进行减1
    
                    案例演示:
                     线程1的任务是打印A和C,线程2的任务是打印B,要求打印B一定要在打印C的前面
             */
            CountDownLatch cdl = new CountDownLatch(1);
    
            // 创建2条线程,执行任务
            MyRunnable1 mr1 = new MyRunnable1(cdl);
            Thread t1 = new Thread(mr1);
            t1.start();
    
    
            MyRunnable2 mr2 = new MyRunnable2(cdl);
            Thread t2 = new Thread(mr2);
            t2.start();//
        }
    }
    

    //4). 执行结果:
    会保证按:A B C的顺序打印。

    //说明:
    CountDownLatch中count down是倒数的意思,latch则是门闩的含义。整体含义可以理解为倒数的门栓,似乎有一点“三二一,芝麻开门”的感觉。

    CountDownLatch是通过一个计数器来实现的,每当一个线程完成了自己的任务后,可以调用countDown()方法让计数器-1,当计数器到达0时,调用CountDownLatch。

    await()方法的线程阻塞状态解除,继续执行。

    CyclicBarrier

    CyclicBarrier的字面意思是可循环使用(Cyclic)的屏障(Barrier)。它要做的事情是,让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续运行。
    //CyclicBarrier构造方法

    public CyclicBarrier(int parties, Runnable barrierAction)
        //parties: 代表要达到屏障的线程数量
        //barrierAction:表示达到屏障后要执行的任务
    

    //CyclicBarrier重要方法:

    public int await()// 每个线程调用await方法告诉CyclicBarrier我已经到达了屏障,然后当前线程被阻塞
    

    //示例代码:

    1). 制作员工线程:

    public class MyRunnable implements Runnable {
    
        CyclicBarrier cb;
    
        public MyRunnable(CyclicBarrier cb) {
            this.cb = cb;
        }
    
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName()+":到会议室了...");
            // 当前线程到达会议室(屏障),暂停
            try {
                cb.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+":离开会议室");
        }
    }
    

    2). 制作开会线程:

    public class MeetingRunnable implements Runnable {
        @Override
        public void run() {
            System.out.println("会议开始,会议的内容是...");
        }
    }
    

    3). 制作测试类:

    public class Test {
        public static void main(String[] args) {
            /*
                CyclicBarrier类:
                    作用:它要做的事情是,让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,
                         所有被屏障拦截的线程才会继续运行。
                    常用方法:
                        public CyclicBarrier(int parties, Runnable barrierAction)
                         parties: 代表要达到屏障的线程数量
                         barrierAction:表示达到屏障后要执行的线程
    
                        public int await() 每个线程调用await方法告诉CyclicBarrier我已经到达了屏障,然后当前线程被阻塞
    
                    案例演示:
                    例如:公司召集5名员工开会,等5名员工都到了,会议开始
             */
            // 创建CyclicBarrier对象
            CyclicBarrier cb = new CyclicBarrier(5,new MeetingRunnable());
    
            MyRunnable mr = new MyRunnable(cb);
            new Thread(mr,"员工1").start();
            new Thread(mr,"员工2").start();
            new Thread(mr,"员工3").start();
            new Thread(mr,"员工4").start();
            new Thread(mr,"员工5").start();
    
    
        }
    }
    

    4). 执行结果:
    在这里插入图片描述
    //使用场景
    使用场景:CyclicBarrier可以用于多线程计算数据,最后合并计算结果的场景。
    需求:使用两个线程读取2个文件中的数据,当两个文件中的数据都读取完毕以后,进行数据的汇总操作。

    Semaphore

    Semaphore的主要作用是控制线程的并发数量。
    synchronized可以起到"锁"的作用,但某个时间段内,只能有一个线程允许执行。
    Semaphore可以设置同时允许几个线程执行。
    Semaphore字面意思是信号量的意思,它的作用是控制访问特定资源的线程数目。
    //Semaphore构造方法:

    public Semaphore(int permits)						permits 表示许可线程的数量
    

    //Semaphore重要方法:

    public void acquire() 表示获取许可
    public void release() 表示释放许可
    

    //- 示例一:同时允许1个线程执行

    1). 制作一个ClassRoom类:

    public class ClassRoom {
        Semaphore sp;
    
        public ClassRoom(Semaphore sp) {
            this.sp = sp;
        }
    
        public void into(){
            // 获得许可
            try {
                sp.acquire();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+":获得许可,进入了教室...");
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+":释放许可,离开教室");
            // 释放许可
            sp.release();
        }
    }
    
    

    //2). 测试类:

    public class Test {
        public static void main(String[] args) {
            // 需求:多线程模拟5个人进入教室,但教室只允许3个人在里面
            // 创建教室对象
            Semaphore sp = new Semaphore(2);
            ClassRoom cr = new ClassRoom(sp);
    
            new Thread(new Runnable() {
                @Override
                public void run() {
                    cr.into();
                }
            }, "同学1").start();
    
            new Thread(new Runnable() {
                @Override
                public void run() {
                    cr.into();
                }
            }, "同学2").start();
    
            new Thread(new Runnable() {
                @Override
                public void run() {
                    cr.into();
                }
            }, "同学3").start();
    
            new Thread(new Runnable() {
                @Override
                public void run() {
                    cr.into();
                }
            }, "同学4").start();
    
    
            new Thread(new Runnable() {
                @Override
                public void run() {
                    cr.into();
                }
            }, "同学5").start();
    
        }
    }
    
    

    Exchanger

    Exchanger(交换者)是一个用于线程间协作的工具类。Exchanger用于进行线程间的数据交换。
    这两个线程通过exchange方法交换数据,如果第一个线程先执行exchange()方法,它会一直等待第二个线程也执行exchange方法,当两个线程都到达同步点时,这两个线程就可以交换数据,将本线程生产出来的数据传递给对方。
    A线程 exchange方法 把数据传递B线程
    B线程 exchange方法 把数据传递A线程
    //Exchanger构造方法:

    public Exchanger()
    

    //Exchanger重要方法:

    public V exchange(V x) 交换数据,参数是要传递给其他线程的数据,返回值是其他线程传递过来的数据
    

    //示例一

    public class MyRunnable1 implements Runnable {
        Exchanger<String> ex;
    
        public MyRunnable1(Exchanger<String> ex) {
            this.ex = ex;
        }
    
        @Override
        public void run() {
            // 线程1 传递数据给 线程2
            try {
                // 线程1,把"信息1"传递给线程2
                String message2 = ex.exchange("信息1");
                System.out.println("线程2 传递给 线程1的信息是:"+message2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    public class MyRunnable2 implements Runnable {
        Exchanger<String> ex;
    
        public MyRunnable2(Exchanger<String> ex) {
            this.ex = ex;
        }
    
        @Override
        public void run() {
            // 线程2 传递数据给 线程1
            try {
                String message1 = ex.exchange("信息2");
                System.out.println("线程1 传递给 线程2的信息:"+message1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    
    

    //2). 制作main()方法:

    public class Test {
        public static void main(String[] args) {
            /*
                Exchanger类:
                    作用:是一个用于线程间协作的工具类。Exchanger用于进行线程间的数据交换。
                    常用方法:
                        public Exchanger()
                        public V exchange(V x)  参数就表示当前线程需要传递的数据,返回值是其他线程传递过来的数据
                    案例演示:
             */
            Exchanger<String> ex = new Exchanger<>();
            MyRunnable1 mr1 = new MyRunnable1(ex);
            new Thread(mr1).start();
    
    
            MyRunnable2 mr2 = new MyRunnable2(ex);
            new Thread(mr2).start();
    
        }
    }
    
    

    //使用场景:可以做数据校对工作
    需求:比如我们需要将纸制银行流水通过人工的方式录入成电子银行流水。为了避免错误,采用AB岗两人进行录入,录入到两个文件中,系统需要加载这两个文件,
    并对两个文件数据进行校对,看看是否录入一致,

    展开全文
  • 自动动手写发包工具

    千次阅读 2012-12-26 15:02:18
    自动动手写发包工具   为了测试服务器大量在线的性能,需要自己写机器人,模拟大量客户端在线的情况。第一步是创建帐号,第一个办法是直接在服务器后台用脚本创建帐号,另一个办法是模拟客户端发包。前者需要登录...

    自动动手写发包工具

     

    为了测试服务器大量在线的性能,需要自己写机器人,模拟大量客户端在线的情况。第一步是创建帐号,第一个办法是直接在服务器后台用脚本创建帐号,另一个办法是模拟客户端发包。前者需要登录到服务器执行,后者可以在其他机器上执行,于是试着用后一种方法实现。

     

    第一步,包含协议头文件,再用C++写一个简单的查询帐号封包。

    发包代码如下:

     

        struct tagMsg& stMsg = m_stMsg.msg;
        memset((void*)&stMsg, 0, sizeof(stMsg));
        // 消息包头的构造
        stMsg.m_stMsgHead.m_uiBodyLength = htonl(21);
        stMsg.m_stMsgHead.m_uiMsgID = htonl(MSGID_ACCOUNT_CREATEROLE_REQUEST);
        stMsg.m_stMsgHead.m_uiUin = htonl(uiUin);
        stMsg.m_stMsgHead.m_shMsgVersion = htons(1);
        // 这里是验证信息,需要特别处理
        stMsg.m_stMsgHead.m_ucSKeyLength = 0x0f;
        memset(&stMsg.m_stMsgHead.m_szSessionKey[0], 0x0c, MAX_SESSIONKEY_LENGTH);
    
        // 协议体初始化
        LPCTSTR lpText = (LPCTSTR)"%d";
        CString string;
        string.Format(lpText, uiUin);
        wsprintfA(&stMsg.m_stMsgBody.m_stAccountCreateRoleRequest.m_szNickName[0], "%S", string);
        stMsg.m_stMsgBody.m_stAccountCreateRoleRequest.m_shWorldID = htons(1);
        stMsg.m_stMsgBody.m_stAccountCreateRoleRequest.m_uiUin = htonl(uiUin);
    

    测试了之后发现服务器收到包与客户端发包并不一致。仔细检查了之后才发现,原来在消息头还插入了两个字节的消息包长度。

    第二步,加入消息包长度,发送封包。代码如下:

     

    #pragma pack(1)
    typedef struct tagCommMsg{
        unsigned short ushLength;
        struct tagKylinMsg msg;
    } TCommMsg;
    #pragma pack()
    unsigned short length = sizeof(short) + sizeof(MSGHEAD) + sizeof(tagCreateRole_Account_Request);    
    m_stMsg.ushLength = htons(length);


    在服务器收到封包还是不一致。用抓包工具看原客户端发送的封包,说明在发送的时候就已经不一致了,那么肯定是客户端在发包之前做了一定的处理。

    第三步,发布协议头是没有经过修改的,但协议体并不是和协议一一对应。那么就直接按照原客户端处理后的发包模拟发包了。

     

            0x0000:  0016 3e70 b800 c89c 1dee aebf 0800 4500  ..>p..........E.
            0x0010:  0063 1d02 4000 3306 033a 0a06 3323 0a06  .c..@.3..:..3#..
            0x0020:  e02a ec56 1f58 305e ee9a 9d4d debf 5018  .*.V.X0^...M..P.
            0x0030:  4071 4ac1 0000 003b 0001 0000 0000 0000  @qJ....;........
            0x0040:  0000 0000 02c1 0000 0141 0000 0000 0000  .........A......
            0x0050:  0014 0a40 6a75 354b 4d47 3036 6100 0000  ...@ju5KMG06a...
            0x0060:  0a40 6a75 354b 4d47 3036 6100 0001 4100  .@ju5KMG06a...A.
            0x0070:  00                                       .
    
    这是原客户端发包抓下来的,看到了吗?从0x0034-0x00337是新增的unsigned short字段,接下来就是MSGHEAD,再接下来是MSGBODY。

    而右边的@ju5KMG06a很明显是MSGHEAD中的key。

    比较协议之间的区别,将相应字段修改成我们需要的字段。比如我们使用的uiUin为321,转换为十六进制是0x141,在封包里找到这个字段的位置是0x006e,0x006d

    直接在程序里把这两个字段改成我们需要的字段就OK啦。代码非常简单,51是从消息头到该字段的偏移。

         *((unsigned int*)((char*)&stMsg.m_stMsgHead + 51)) = htonl(uiUin);
    修改之后,就可以顺利地实现到我们的目的,其他字段的修改也同理。创建帐号的协议同样道理也可以实现的。

    小结一下步骤:

    一、用原客户端发包

    二、用工具过滤,抓指定协议的包

    三、找到关注字段,将相应字段修改

    四、模拟客户端发包

    附:tcpdump抓包过滤   tcpdump -i eth1  -XX 'ip[54:2]==701' -s 0

    说明一下:-i eth1只监听eth1网口,-XX是将包详细十六进制打出,更直观看封包内容,'ip[54:2]==701'表示IP头开始第54字节处的两个字节值为701,这里是消息号

    -s 0表示不仅仅打印包头,tcpdump默认只打印0x52字节包头,加了这个参数才能看到包体内容。

    如果还需要过滤,可以加src XX发包源过滤,dst XX发包目的过滤,port XX端口过滤。

    PS:当然有很有工具如WPE,XNetHelper就已经实现了修改封包的功能了。自己写的至少有两个好处,第一个,有些抓包工具是被杀毒软件认为是病毒,需要关闭杀毒软件再操作。第二个,自己写的程序更方便集成到其他系统中去。

    展开全文
  • 打开适配器以后,调用 pcap_sendpacket() 来发送手工制作的数据包。 pcap_sendpacket() 的参数有一个要包涵发送数据的缓冲区,缓冲的长度,以及用来发送数据的适配器。注意,缓冲数据将直接发送到网络,而不会进行...

    时间问题,本次教程就不做详细的代码分析了,直接拿来了发包的两个实例。可以通过读以下代码对发包的程序做一下了解。

    下节我们开始程序实战。

    使用 pcap_sendpacket() 发送单个数据包

    下面的代码展示了发送一个数据包的最简单的方式。打开适配器以后,调用 pcap_sendpacket() 来发送手工制作的数据包。pcap_sendpacket() 的参数有一个要包涵发送数据的缓冲区,缓冲的长度,以及用来发送数据的适配器。注意,缓冲数据将直接发送到网络,而不会进行任何加工和处理。这就意味着应用程序需要创建一个正确的协议首部,来使这个数据包更有意义。

    #include <stdlib.h>
    #include <stdio.h>
    
    #include <pcap.h>
    
    
    void main(int argc, char **argv)
    {
    pcap_t *fp;
    char errbuf[PCAP_ERRBUF_SIZE];
    u_char packet[100];
    int i;
    
        /* 检查命令行参数的合法性 */
        if (argc != 2)
        {
            printf("usage: %s interface (e.g. 'rpcap://eth0')", argv[0]);
            return;
        }
        
        /* 打开输出设备 */
        if ( (fp= pcap_open(argv[1],            // 设备名
                            100,                // 要捕获的部分 (只捕获前100个字节)
                            PCAP_OPENFLAG_PROMISCUOUS,  // 混杂模式
                            1000,               // 读超时时间
                            NULL,               // 远程机器验证
                            errbuf              // 错误缓冲
                            ) ) == NULL)
        {
            fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n", argv[1]);
            return;
        }
    
        /* 假设在以太网上,设置MAC的目的地址为 1:1:1:1:1:1 */
        packet[0]=1;
        packet[1]=1;
        packet[2]=1;
        packet[3]=1;
        packet[4]=1;
        packet[5]=1;
        
        /* 设置MAC源地址为 2:2:2:2:2:2 */
        packet[6]=2;
        packet[7]=2;
        packet[8]=2;
        packet[9]=2;
        packet[10]=2;
        packet[11]=2;
        
        /* 填充剩下的内容 */
        for(i=12;i<100;i++)
        {
            packet[i]=i%256;
        }
    
        /* 发送数据包 */
        if (pcap_sendpacket(fp, packet, 100 /* size */) != 0)
        {
            fprintf(stderr,"\nError sending the packet: \n", pcap_geterr(fp));
            return;
        }
    
        return;
    }
    

    发送队列

    pcap_sendpacket() 提供了一种简单而直接的方法来发送单个数据包,而send queues则提供了一种高级的,强大的,结构更优的方法来发送一组数据包。发送队列是一个容器,它能容纳不同数量的数据包,这些数据包将被发送到网络上。队列有大小,它代表了它能存储的数据包的最大数量。

    发送队列通过调用 pcap_sendqueue_alloc() 函数创建,并且需要指定队列的大小。

    一旦发送队列被创建, pcap_sendqueue_queue() 就可以将数据包添加到发送队列中。这个函数的参数包含一个pcap_pkthdr 的结构体,它包含时间戳和长度,同时,参数还包含一个指向数据包数据的缓冲。这些参数和那些被pcap_next_ex()pcap_handler()接收到的数据相同,因此,为那些刚刚捕获到的,或是从文件读取出来的数据包排队,就相当于把三个参数传递给pcap_sendqueue_queue()

    WinPcap提供了 pcap_sendqueue_transmit() 函数来发送一个队列。请注意第三个参数:如果非零,那么发送过程将是同步进行,也就是说,只有时间戳相符的数据包才会被处理。这个操作需要消耗大量的CPU资源,因为同步操作由内核驱动中的"忙等 (busy wait)"循环来实现的。尽管这个操作对CPU的要求很高,但它对包传送的处理结果,通常是很精确的。(通常在数微秒左右,或更小)

    请注意,使用 pcap_sendqueue_transmit() 要比pcap_sendpacket() 来发送一系列数据更加有效率,因为发送队列保存在内核级的缓冲区,因此,减少了上下文交换的次数。

    当队列不再需要时,我们可以使用 pcap_sendqueue_destroy() 来释放它所占用的内存。

    下一个程序将演示如何使用发送队列。先用 pcap_open_offline() 打开一个捕获文件,然后,将文件中的数据包移到已分配的发送队列。这时,就可以发送队列了,如果用户指定了同步,那么它将同步发送队列。

    注意,堆文件的链路层将会那些发送数据包接口中的一个进行比较,那些接口使用 pcap_datalink() 发送数据包。当比较的结果不相同,那么就会打印出警告信息。捕获文件的链路层和适配器的链路层相一致是非常重要的,不然,发送将变得毫无意义。


    #include <stdlib.h>
    #include <stdio.h>
    
    #include <pcap.h>
    #include <remote-ext.h>
    
    void usage();
    
    void main(int argc, char **argv)
    {
        pcap_t *indesc,*outdesc;
        char errbuf[PCAP_ERRBUF_SIZE];
        char source[PCAP_BUF_SIZE];
        FILE *capfile;
        int caplen, sync;
        u_int res;
        pcap_send_queue *squeue;
        struct pcap_pkthdr *pktheader;
        u_char *pktdata;
        float cpu_time;
        u_int npacks = 0;
        
        /* 检查命令行参数的合法性 */
        if (argc <= 2 || argc >= 5)
        {
            usage();
            return;
        }
            
        /* 获取捕获文件长度 */
        capfile=fopen(argv[1],"rb");
        if(!capfile){
            printf("Capture file not found!\n");
            return;
        }
        
        fseek(capfile , 0, SEEK_END);
        caplen= ftell(capfile)- sizeof(struct pcap_file_header);
        fclose(capfile);
                
        /* 检查时间戳是否合法 */
        if(argc == 4 && argv[3][0] == 's')
            sync = TRUE;
        else
            sync = FALSE;
    
        /* 开始捕获 */
        /* 根据WinPcap的新语法创建一个源字符串 */
        if ( pcap_createsrcstr( source,         // 源字符串
                                PCAP_SRC_FILE,  // 我们要打开的文件
                                NULL,           // 远程主机
                                NULL,           // 远程主机的端口
                                argv[1],        // 我们要打开的文件名
                                errbuf          // 错误缓冲
                                ) != 0)
        {
            fprintf(stderr,"\nError creating a source string\n");
            return;
        }
        
        /* 打开捕获文件 */
        if ( (indesc= pcap_open(source, 65536, PCAP_OPENFLAG_PROMISCUOUS, 1000, NULL, errbuf) ) == NULL)
        {
            fprintf(stderr,"\nUnable to open the file %s.\n", source);
            return;
        }
    
        /* 打开要输出的适配器 */
        if ( (outdesc= pcap_open(argv[2], 100, PCAP_OPENFLAG_PROMISCUOUS, 1000, NULL, errbuf) ) == NULL)
        {
            fprintf(stderr,"\nUnable to open adapter %s.\n", source);
            return;
        }
    
        /* 检查MAC的类型 */
        if (pcap_datalink(indesc) != pcap_datalink(outdesc))
        {
            printf("Warning: the datalink of the capture differs from the one of the selected interface.\n");
            printf("Press a key to continue, or CTRL+C to stop.\n");
            getchar();
        }
    
        /* 分配发送队列 */
        squeue = pcap_sendqueue_alloc(caplen);
    
        /* 从文件中将数据包填充到发送队列 */
        while ((res = pcap_next_ex( indesc, &pktheader, &pktdata)) == 1)
        {
            if (pcap_sendqueue_queue(squeue, pktheader, pktdata) == -1)
            {
                printf("Warning: packet buffer too small, not all the packets will be sent.\n");
                break;
            }
    
            npacks++;
        }
    
        if (res == -1)
        {
            printf("Corrupted input file.\n");
            pcap_sendqueue_destroy(squeue);
            return;
        }
    
        /* 发送队列 */
        
        cpu_time = (float)clock ();
    
        if ((res = pcap_sendqueue_transmit(outdesc, squeue, sync)) < squeue->len)
        {
            printf("An error occurred sending the packets: %s. Only %d bytes were sent\n", pcap_geterr(outdesc), res);
        }
        
        cpu_time = (clock() - cpu_time)/CLK_TCK;
        
        printf ("\n\nElapsed time: %5.3f\n", cpu_time);
        printf ("\nTotal packets generated = %d", npacks);
        printf ("\nAverage packets per second = %d", (int)((double)npacks/cpu_time));
        printf ("\n");
    
        /* 释放发送队列 */
        pcap_sendqueue_destroy(squeue);
    
        /* 关闭输入文件 */
        pcap_close(indesc);
    
        /* 
         * 释放输出适配器 
         * IMPORTANT: 记得一定要关闭适配器,不然就不能保证 
         * 所有的数据包都回被发送出去
         */
        pcap_close(outdesc);
    
    
        return;
    }
    
    void usage()
    {
        
        printf("\nSendcap, sends a libpcap/tcpdump capture file to the net. Copyright (C) 2002 Loris Degioanni.\n");
        printf("\nUsage:\n");
        printf("\t sendcap file_name adapter [s]\n");
        printf("\nParameters:\n");
        printf("\nfile_name: the name of the dump file that will be sent to the network\n");
        printf("\nadapter: the device to use. Use \"WinDump -D\" for a list of valid devices\n");
        printf("\ns: if present, forces the packets to be sent synchronously, i.e. respecting the timestamps in the dump file. This option will work only under Windows NTx.\n\n");
    
        exit(0);
    }
    

    通过对以上代码阅读,大家可以了解到发包的简单过程,在下一节,我为大家带来Winpcap编程实战,综合运用以上方法来实现主机通信!
    展开全文
  • TCP/UDP/ICMP/IGMP发包工具

    热门讨论 2012-03-12 15:41:14
    可以制作各种IP数据,自定义L2 Header、L3 Header和L4 Header等,包括MAC、IP包头、报文内容定制等,通过该工具对指定的地点发送设置的数据,用于各种网络性能、特殊报文处理等测试。
  • 制作无数爬虫,可能都是比较简单的网站,今天自己用java一个测试数据发现了问题 这是我自己写的路由。 这里的意思是获取前端传过的的全部数据然后json返回(为什么不直接返回?,我上去就是一巴掌,当然是执行一些...
  • 发包 线程池 教学目标 能够使用Lock解决线程安全问题 能够描述ConcurrentHashMap类的作用 能够描述CountDownLatch类的作用 能够描述CyclicBarrier类的作用 能够表述Semaphore类的作用 能够描述Exchanger类...
  • 【线程安全、volatile关键字、原子性、并发包、死锁、线程池】 内容 线程安全 synchronized关键字\Lock接口 同步代码块 同步方法 Lock锁 高并发可见性问题 volatile关键字 锁机制 高并发原子性问题 锁机制 ...
  •  * 老伴负责写新订单 员工不断查看订单制作奶茶 写的期间不允许查看 (仅允许单个写)  * 多个员工可同时查看订单 查看时老板不允许写新订单 (可多个读)   private static final ReentrantLock ...
  • 在软件外包过程中,发包方似乎处于主动位置,可以决定是否和如何外包,哪些内容需要外包,并可以自主选择合适的承包方。但是,企业经营活动高度复杂,风险无处不在。软件外包作为软件生产的新方式同样存在各种风险,...
  • day12【线程安全解决synchronized,并发包】第一章 synchronized关键字1.1 多行代码的原子性问题1.2 synchronized关键字概述1.3 同步代码块1.4 同步方法1.5 Lock锁第二章 并发包2.1 CopyOnWriteArrayList2.2 ...
  • Day08【线程状态、volatile关键字、原子性、并发包、死锁、线程池】 今日目标 线程安全 volatile关键字 原子性 并发包 死锁 线程池 教学目标 能够说出volatile关键字的作用 实现成员变量多个线程修改后的可见...
  • 如今大多数SEO快排都宣称自己是安全的SEO发包技术,但这种可能的发包技术原理更能解释为什么百度指数比百度表现更好。如今,带来的是“用户行为影响排名、刷点击和快排分配原则”。但愿这次的SEO技术分享对大家了解...
  • 使shell命令发包软件<您可以这样做:>调用外部程序命令<;>那样的话,结局太快了!中间输入命令必须等待程序发声并扫描容量设备。扫描完成后有没有办法退出?您尝试在EOF中编写:这通常是在1成功执行,2...
  • day10【线程安全、volatile关键字、原子性、并发包、死锁、线程池】 今日内容 线程安全 volatile关键字 原子类 并发包 线程池 死锁 教学目标 能够解释安全问题的出现的原因 能够使用同步代码块解决线程安全...
  • 前言 大家好,又到了Python办公...另外还有一份Excel合同信息表,其中是所有甲方(发包人)在合同中需要填写的内容 可见一行为一个公司的全部信息,现在需要把Excel中每一个公司的信息填入空白Word合同模板中,生成各公
  • 使用commandLine制作ipa包

    千次阅读 2013-05-13 11:46:16
    使用commandLine制作ipa包   转载▼ 研究了下jenkins.大概知道了xcode进行自动化测试的流程. 对我来说这个流程中我需要了解的是自动打包,自动上传,自动化测试还有待研究(代码工作量比较大).如果真自动化...
  • 多线程基础 多线程的实现方式 (1) 继承Thread类 创建类, 继承Thread 重写run()方法 将线程要执行的内容放到run()中 创建Thread的子类对象 调用start()方法开启线程 ... // 已经存在了一个主线程, 还有一条垃圾回收...
  • 俄罗斯引进的tibbo全新的物联网开发理念,拥有完整的开发环境,开发所需的TPS硬件,主流的...在这里你没有太多的约束,可以尽情的发挥自己的想象,来制作自己想要的产品。给了用户最大的自由度。你可以尽情的发挥。
  • 在内网实现类似QQ通知窗口(发包/收包/弹出通知)

    千次阅读 热门讨论 2008-11-04 11:52:00
     接下来就是制作弹出窗口了. 上网查了一下,很多地方都在转载一篇文章利用C# 实现任务栏通知窗口>>,仔细研究了一下这篇文章发现还是很不错的,弹出的窗口也可以随着不同的背景图片实现不规则的窗口,引用来自己实现了...
  • 这里我们自己动手实现 CoutDownLatch,使用LockSupport 和 等待队列, 如何无法理解,可以学习 《ReentrantLock 的实现》package com.john.learn.high.concurent.ch03.tools; import java.util.Iterator;...
  • 游戏抓包制作外挂

    2014-04-12 00:09:08
    可以用它制作外挂 他只是修改器怎么做就要看你自己了
  • 工程设计费,即工程设计收费,是设计人根据发包人的委托,提供编制建设项目初步设计文件、施工图设计文件、非标准设备设计文件、施工图预算文件、竣工图文件等服务所收取的费用。工程设计收费标准2002年国家发展计划...
  • 网游外挂之制作流程

    千次阅读 2012-05-22 15:03:16
    很多人都对网游外挂的制作很感兴趣,在这篇文章里,我向大家简单介绍一下一款网游外挂的大致制作流程。  首先,我想说明几点: 第一,这篇文章并不是具体教你如何写外挂,只是带你大致浏览一下网游外挂的制作流程...
  • 如何制作USB管理软件

    2017-01-21 14:15:55
    http://gualihuala.pc.ev123.com.cn/gualihuala/vip_doc/3432931.html 可以制作你的USB精灵 主要功能: 计算机与USB通信 USB监测
  • 接着在telnet窗口中输入任何字符,这些字符会发动到你的服务器,为了验证你收到这些字符,当你的服务器收到这些包后,可以给telnet也发包。不过注意在telnet客户端发包的你每敲入一个字符就发送一个包,而不是等你...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,111
精华内容 1,244
关键字:

发包制作