想实现模拟发送http数据包, 我的理解是这样: 用class 来构造http数据包的头部和 body。
body的部分我是想讲一个文件按照byte 输入。 然后来发送。问题是: OutputStream.write() 处理的是byte。 我如何将我构造的http数据包的类对象 变成  byte, 然后给write 写入buffer中? 是要将每个变量 挨个加起来吗? 还是有其他的办法? 如果能给个类似的例子 就更好了。 
谢谢 

解决方案 »

  1.   

    没那么复杂,用开源的 HttpClient 包就行了,这些问题全都帮你处理好了。POST 和 GET 都轻松搞定,可以Google下样例代码,大把大把的。
      

  2.   

    我这个不是跟 web server 通信。 是在两台pc上 通过TCP 来 传 http 包。 我要自己构造 http 数据包, 然后传送。 有个实验 是要在传递这些数据包的时候 进行一些其他处理, 然后在对方接收到之后  对数据进行分析。 你说的 post 和 get  是这个意思吗
      

  3.   

    使用HttpURLConnection就可以实现的,他们说的都不怎么靠谱,我直接给你点代码,给点分哈哈。
    URL url = new URL("http://oa.opple.com/names.nsf?Login"); //提交的地址 
     //STEP.1.建立连接  POST /names.nsf?Login HTTP/1.1
     HttpURLConnection con = (HttpURLConnection) url.openConnection(); 
     con.setRequestMethod("POST"); //设置方法为Post 
     //STEP.2.设置Cookie 根据你的js做的
     con.setRequestProperty("Cookie", "A="+currname+"; B="+currpwd+"; LastVisitUserName=" + currname +";"); 
     con.setDoInput(true);
     con.setDoOutput(true);
     //STEP.3.发送post数据 
     BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(con.getOutputStream())); 
     writer.write(postdata); writer.flush(); writer.close(); 
     //STEP.4.获取返回数据 
     System.out.println("返回的代码是:"+con.getResponseCode()+"定向地址为"+con.getHeaderField("location"));
     BufferedReader reader = new BufferedReader(new InputStreamReader(con.getInputStream())); 
     String line; 
     System.out.println(new Date());
     while ((line = reader.readLine()) != null) 
     { System.out.println(line); } 
     reader.close(); 
     con.disconnect(); 
      

  4.   

    不对啊 你这个还是 跟webserver 通信。 
    我说的不是这个意思。 我说的是自己构造http数据包后 如何通过 TCP socket发送出去。 
      

  5.   

    那只能给你点片段核心代码,你自己好好看看,SOCKET模拟HTTP的请求:
     StringBuilder header = new StringBuilder();
                BufferedReader br = null;
                BufferedWriter bw = null;
                StringBuilder accept = new StringBuilder("GET / HTTP/1.1\r\n");
                accept.append("User-Agent: Java/1.6.0_20\r\n");
                accept.append("Host: "+domain.getDomainname()+":"+domain.getPort()+"\r\n");
                accept.append("Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2\r\n");
                accept.append("Connection: Close\r\n");
                accept.append("\r\n");
                try {                Socket socket = new Socket();                //socekt连接ip,port,5秒钟后没有连接指定ip则跑出SocketTimeOutException异常,表示连接超时
                    socket.connect(new InetSocketAddress(InetAddress.getByName(domain.getIp()), domain.getPort()),5);
                    socket.setSoTimeout(5);
                    br = new BufferedReader(new InputStreamReader(socket.getInputStream(),"GBK"));
                    bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
                    bw.write(accept.toString());
                    bw.flush();
                    String firstLine = br.readLine();
                    if(firstLine != null){
                        stateCode = Integer.parseInt(firstLine.split(" ")[1]);
                        header.append(firstLine);
                    }
                    state = (stateCode == 200)? 1 : 2;
                    String line = "";
                    while(!"".equals((line = br.readLine()))){
                        header.append(line+"\n");
                    } 
      

  6.   

    楼主的要求比较怪异,既然只不过是两台电脑用TCP通讯,为啥你非要用HTTP协议呢?建议直接抛开标准协议。建立Socket后,直接用ObjectOutputStream和ObjectInputStream包装下,就可以直接发送对象了(必须是可序列化的),简单又方便。否则光协议解析和处理,就要浪费自己大量代码。
      

  7.   

    我猜楼主你是想模拟传输层传输,如果利用java好像只能通过byte传输,你可以写个方法将你的Http报文转成字符串形式,然后转换成byte数组传输
      

  8.   

    谢谢各位的回答。  请问一下 abcmsnet:
    StringBuilder accept = new StringBuilder("GET / HTTP/1.1\r\n");
      accept.append("User-Agent: Java/1.6.0_20\r\n");
      accept.append("Host: "+domain.getDomainname()+":"+domain.getPort()+"\r\n");
      accept.append("Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2\r\n");
      accept.append("Connection: Close\r\n");
      accept.append("\r\n");以上这个代码就是你模拟创建的 http数据包是吧?  
    这是一般的方法吗?  
    我的想法是 用一个类 来封装这些数据结构,然后发送。
    其中 这个类的每个对象的内容都是变化的, 也就是 发送出去的 http
    包都是不一样的。 我需要的就是这种效果。
    那么我是不是先创建这个类,然后用你的办法,将所有的类变量append 到accept 中, 然后发送。 我的理解对吗?  我只是模拟http数据包的发送与接受,不用解包,只要收到就行。 
      

  9.   

    你是说你创建一个类,将http各种参数赋给这个类,然后发送给接收方是可以的,用下面的方法将自定义类拆解成字节,然后发送这个类字节给接收方,接收方可以再转换成类就行了。不过还得调试调试。
    ByteArrayOutputStream bao=new ByteArrayOutputStream();
    ObjectOutputStream oop=new ObjectOutputStream(bao);
    oop.writeObject(myClass);//这里把自定义类注入进去
    ByteBuffer bba=ByteBuffer.wrap(bao.toByteArray());
    这个bba就是类序列化后的字节,然后socket的send发送给对方,然后接收方可以再使用ObjectInPutStream再解析成自定义类。
    那上面这种一般是TCP协议的socket程序互相发送自定义类的方法。
      

  10.   

    你要自己通过 Socket 来发送 HTTP 数据包?哎,我看楼主还是不要费这个心了,简单的好弄的,但是要能应用于生产环境的,那可没有那么简单!JDK 中有现成的 HttpURLConnection
    Apache 中有现成的 HttpComponent, HttpClient 4.x
    Apache Commons 中有现成的 HttpClient 3.x有这么多现在的工具为什么不用呢?你认为你能写得比这里工具好?