V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
onice
V2EX  ›  Java

Java 怎么操作网络协议的?

  •  
  •   onice · 2016-06-16 23:26:09 +08:00 · 3921 次点击
    这是一个创建于 3074 天前的主题,其中的信息可能已经有所发展或是发生改变。

    想写一个网络压力测试工具,需要自己构造数据包,然后再尽可能的利用系统资源达到最大的数据包生产速度再通过网卡送出去。

    不知道用 Java 可行不?感觉性能会受限于 JVM 。

    其实 C 肯定是最快,,但现在只会 Java 和一些 Python 基础- -!

    最好是能跨平台,,但感觉有些难,毕竟各个操作系统提供的操作网络的接口不一样,目前所知 JVM 也没有屏蔽掉这个差异。即使是不能跨平台,至少在 Win 下要能用。 Linux 平台的话 Kali 上肯定有工具可以用。

    请大家给点思路啦 - -

    第 1 条附言  ·  2016-06-17 08:43:07 +08:00
    补充一下,我想测试的是 TCP SYN 短链接的。另外,还需要模拟客户浏览器访问网站,类似达到 CC 攻击的效果。 UDP 洪水攻击也可能需要考虑实现,用于测试主机防火墙。
    15 条回复    2016-06-17 18:05:25 +08:00
    pagxir
        1
    pagxir  
       2016-06-16 23:35:43 +08:00
    go 会满足你这些要求的。
    teemoer
        2
    teemoer  
       2016-06-17 00:14:20 +08:00
    package wzh.Http;

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.PrintWriter;
    import java.net.URL;
    import java.net.URLConnection;
    import java.util.List;
    import java.util.Map;

    public class HttpRequest {
    /**
    * 向指定 URL 发送 GET 方法的请求
    *
    * @param url
    * 发送请求的 URL
    * @param param
    * 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
    * @return URL 所代表远程资源的响应结果
    */
    public static String sendGet(String url, String param) {
    String result = "";
    BufferedReader in = null;
    try {
    String urlNameString = url + "?" + param;
    URL realUrl = new URL(urlNameString);
    // 打开和 URL 之间的连接
    URLConnection connection = realUrl.openConnection();
    // 设置通用的请求属性
    connection.setRequestProperty("accept", "*/*");
    connection.setRequestProperty("connection", "Keep-Alive");
    connection.setRequestProperty("user-agent",
    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
    // 建立实际的连接
    connection.connect();
    // 获取所有响应头字段
    Map<String, List<String>> map = connection.getHeaderFields();
    // 遍历所有的响应头字段
    for (String key : map.keySet()) {
    System.out.println(key + "--->" + map.get(key));
    }
    // 定义 BufferedReader 输入流来读取 URL 的响应
    in = new BufferedReader(new InputStreamReader(
    connection.getInputStream()));
    String line;
    while ((line = in.readLine()) != null) {
    result += line;
    }
    } catch (Exception e) {
    System.out.println("发送 GET 请求出现异常!" + e);
    e.printStackTrace();
    }
    // 使用 finally 块来关闭输入流
    finally {
    try {
    if (in != null) {
    in.close();
    }
    } catch (Exception e2) {
    e2.printStackTrace();
    }
    }
    return result;
    }

    /**
    * 向指定 URL 发送 POST 方法的请求
    *
    * @param url
    * 发送请求的 URL
    * @param param
    * 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
    * @return 所代表远程资源的响应结果
    */
    public static String sendPost(String url, String param) {
    PrintWriter out = null;
    BufferedReader in = null;
    String result = "";
    try {
    URL realUrl = new URL(url);
    // 打开和 URL 之间的连接
    URLConnection conn = realUrl.openConnection();
    // 设置通用的请求属性
    conn.setRequestProperty("accept", "*/*");
    conn.setRequestProperty("connection", "Keep-Alive");
    conn.setRequestProperty("user-agent",
    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
    // 发送 POST 请求必须设置如下两行
    conn.setDoOutput(true);
    conn.setDoInput(true);
    // 获取 URLConnection 对象对应的输出流
    out = new PrintWriter(conn.getOutputStream());
    // 发送请求参数
    out.print(param);
    // flush 输出流的缓冲
    out.flush();
    // 定义 BufferedReader 输入流来读取 URL 的响应
    in = new BufferedReader(
    new InputStreamReader(conn.getInputStream()));
    String line;
    while ((line = in.readLine()) != null) {
    result += line;
    }
    } catch (Exception e) {
    System.out.println("发送 POST 请求出现异常!"+e);
    e.printStackTrace();
    }
    //使用 finally 块来关闭输出流、输入流
    finally{
    try{
    if(out!=null){
    out.close();
    }
    if(in!=null){
    in.close();
    }
    }
    catch(IOException ex){
    ex.printStackTrace();
    }
    }
    return result;
    }
    }
    1423
        3
    1423  
       2016-06-17 00:18:32 +08:00
    pcap4j
    Reficul
        4
    Reficul  
       2016-06-17 00:32:19 +08:00 via Android
    Go 去官网做完教程练习,找个 net 包发包的 demo 改改就好啦。

    跨平台,而且写的时候不需要考虑异步和阻塞,直接操作 byte 构造数据包,用好 buff ,多开几个 goroutine 做并发的 woker 就能尽可能利用到资源啦
    Srar
        5
    Srar  
       2016-06-17 03:47:19 +08:00
    google: java aio
    tobyxdd
        6
    tobyxdd  
       2016-06-17 08:01:18 +08:00 via Android
    这需求哪个语言不行?这也能用来安利 go ??
    weiweiwitch
        7
    weiweiwitch  
       2016-06-17 08:38:19 +08:00
    楼主根本没说清楚这个网络压力测试是用长连接还是短连接。是走 tcp 协议还是其他协议。到底要测什么的压力。

    就我所知,常见的语言都可以用来写网络压力测试工具。就我的经验,大多数情况下,网络压力测试工具尚未发挥最大性能时,对面的被测试服务通常是先挂掉了。

    LZ 应该先用自己最熟悉的语言写个压力测试工具,等遇到瓶颈了在考虑具体问题具体分析。

    另外,写任何东西,都不要把性能问题考虑的很重!程序性能对于一个项目来说,通常都是很小的一个因素。后面的开发迭代可以有各种方法把性能提上去。太早考虑性能只会让自己裹足不前。
    araraloren
        8
    araraloren  
       2016-06-17 08:56:42 +08:00
    ~~ 楼主的意思是自己构造数据包,然后发送,那就得用`raw socket`,即原始套接字,
    同 6 楼,我想大部分语言都能出色的完成这个任务。。这也能安利 go..
    flyfowl
        9
    flyfowl  
       2016-06-17 08:59:41 +08:00
    听说 Python 有个 Scapy ,很方便
    sodaless
        10
    sodaless  
       2016-06-17 09:01:55 +08:00
    从 Socket 开始写,一层一层包 header 和 payload
    ryd994
        11
    ryd994  
       2016-06-17 09:30:38 +08:00 via Android
    用 Java ……你是压测服务器还是压测本机?
    如果数据不是太复杂的话还是建议 C 或者 C++
    凑合写写性能都不会太差的,靠-Ofast 卍解
    Neveroldmilk
        12
    Neveroldmilk  
       2016-06-17 09:34:40 +08:00
    java 当然可以自定协议,要知道某个著名扶墙工具就是 java 写的。
    br00k
        13
    br00k  
       2016-06-17 10:03:43 +08:00
    weirdbird
        14
    weirdbird  
       2016-06-17 15:54:22 +08:00
    @Neveroldmilk 什么名字?
    Neveroldmilk
        15
    Neveroldmilk  
       2016-06-17 18:05:25 +08:00
    @weirdbird Finalspeed 和 Xsocks 。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2883 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 19ms · UTC 13:47 · PVG 21:47 · LAX 05:47 · JFK 08:47
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.