当前页面: 开发资料首页 → J2EE 专题 → 急啊,高手过来看看啊!关于HTTP协议传输文件的问题!
急啊,高手过来看看啊!关于HTTP协议传输文件的问题!
摘要: 急啊,高手过来看看啊!关于HTTP协议传输文件的问题!
现先说一下实现的功能。就是用户在客户端把文件通过HTTP协议上传到服务器,服务器是用SOCKET自己写的一个接收文件的。本想把文件转成字节,存储在对象的形式并序列化后发送到服务器,服务器接收后反序列化。进行相关操作。
代码如下:
server:
public void run()
{
ServerSocket server_socket;
try
{
int port=Integer.parseInt(serverPort);
server_socket= new ServerSocket(port);
sm.setMsg("服务器已经启动:开始监听"+port+"端口");
System.out.println("服务器已经启动:开始监听"+port+"端口");
//显示启动信息;
while(true)
{
Socket socket=server_socket.accept();
System.out.println("New Connection accepted:"+socket.getInetAddress()+":"+socket.getPort());
//创建分线程;
// sm.setMsg("服务器接收到新连接!");
try
{
httpRequestHandler request=new httpRequestHandler(socket);
Thread thread=new Thread(request);
thread.start();
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
class httpRequestHandler implements Runnable
{
final static String CRLF="/r/n";
Socket socket;
InputStream input;
PrintStream output;
BufferedReader br;
ObjectInputStream in;
public httpRequestHandler(Socket ssocket) throws Exception
{
this.socket=ssocket;
//this.input=socket.getInputStream();
//this.output=new PrintStream(socket.getOutputStream());
//this.br=new BufferedReader(new InputStreamReader(ssocket.getInputStream()));
try
{
//in = new ObjectInputStream(ssocket.getInputStream());
System.out.println("begin socket.getInputStream()");
input=socket.getInputStream();
byte[] buf = new byte[2048];
int len = input.read(buf);
System.out.println("len="+len);
ObjectInputStream oins =null;
String tempstr=new String(buf,"gb2312");
System.out.println(tempstr);
oins = new ObjectInputStream(new ByteArrayInputStream(buf)); ****///程序运行到此处出错。请大家帮忙。
System.out.println("begin read Msg");
ObjectMsg msg=(ObjectMsg)oins.readObject();
oins.close();
System.out.println("end socket.getInputStream()");
input.close();
socket.close();
//in=new ObjectInputStream(input);
System.out.println("socket.getInputStream()ok");
}
catch(Exception ex)
{
System.out.println("socket.getInputStream()出错:"+ex.getMessage());
ex.printStackTrace();
}
}
////////////////////////////////////////////////////////////////////////////////
客户端:
public String SendFile(String filePath,String filename)
{
String retM = "";
String httpUrl="http://127.0.0.1:9999";
BufferedReader br=null;
try
{
//准备连接URL;
myURL=new URL(httpUrl);
myHttpCon=(HttpURLConnection)myURL.openConnection();
myHttpCon.setUseCaches(false);
myHttpCon.setDoOutput(true);
myHttpCon.setDoInput(true);
// myHttpCon.setRequestMethod("POST");
// myHttpCon.connect();
//输出流;
ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(byteOut);
//信息;
ObjectMsg outMsg=new ObjectMsg();
//byte[] buffer=new byte[2056];
// FileInputStream filein=new FileInputStream(filePath);
// filein.read(buffer,0,2056);
outMsg.setSendMsg("it is test,i want to success,please help me!thanks a lot.");
outMsg.setId(1);
outMsg.setName(filename);
outMsg.setSendMsg("test,success");
// outMsg.setValue(buffer);
//输出到缓冲区;
out.writeObject(outMsg);
out.flush();
out.close();
byte[] buf=byteOut.toByteArray();
//输出信息到服务器;
myHttpCon.setRequestProperty("Content-type","application/octet-stream");
myHttpCon.setRequestProperty("Content-length",""+buf.length);
DataOutputStream dataOut = new DataOutputStream(myHttpCon.getOutputStream());
dataOut.write(buf);
dataOut.flush();
dataOut.close();
//响应消息流;
ObjectInputStream in = new ObjectInputStream(myHttpCon.getInputStream());
//接收响应对象;
ObjectMsg msgIn=(ObjectMsg)in.readObject();
in.close();
retM="ok";
}
catch(Exception ex)
{
retM="error";
ex.printStackTrace();
}
return retM;
}
}
/////////////////////////////////////////////////////////////////////////////
现在用到的对象如下:
public class ObjectMsg implements Serializable{
private int id;
private String name;
private String sendMsg;
// private byte[] value;
private static final long serialVersionUID = 65474834800040131L;
public ObjectMsg()
{
}
public ObjectMsg(int iid,String sname,String ssendMsg)
{
this.id=iid;
this.name=sname;
this.sendMsg=ssendMsg;
// this.value=bvalue;
}
public void setId(int iid)
{
this.id=iid;
}
public void setName(String sname)
{
this.name=sname;
}
public void setSendMsg(String ssendMsg)
{
this.sendMsg=ssendMsg;
}
// public void setValue(byte[] bvalue)
// {
// this.value=bvalue;
// }
public int getId()
{
return id;
}
public String getName()
{
return name;
}
public String getSendMsg()
{
return sendMsg;
}
// public byte[] getValue()
// {
// return value;
// }
}
运行后。出现如下错误:在服务器代码的
oins = new ObjectInputStream(new ByteArrayInputStream(buf));
System.out.println("begin read Msg");
ObjectMsg msg=(ObjectMsg)oins.readObject();
出错如下:接下页,发不了了
New Connection accepted:/127.0.0.1:1192
begin socket.getInputStream()
len=394
POST / HTTP/1.1
Content-type: application/octet-stream
Content-length: 136
Cache-Control: no-cache
Pragma: no-cache
User-Agent: Java/1.5.0_03
Host: 127.0.0.1:9999
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive
java.io.StreamCorruptedException: invalid stream header
at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:753)
at java.io.ObjectInputStream.
(ObjectInputStream.java:268)
at filetransfersserver.com.httpRequestHandler.(HttpServer.java:105)
at filetransfersserver.com.HttpServer.run(HttpServer.java:62)
socket.getInputStream()出错:invalid stream header
java.lang.NullPointerException
其中有段文件拷不了,就是我的对应那段。好像对象数据已经传上来了。大家帮忙看看是什么原因啊,谢谢1
怎么没有人啊,郁闷
HTTP协议可以这样用吗?
如果是 HTTP 就写个servlet 下载页面就可以了,客户端就是一个下载程序。
您的服务程序跟http协议一点关系都没有!
当你用TCP/IP协议时,你才使用socket!
如果是http你需要使用servlet的request接受
学习!
up!
mark!
估计楼主把http跟socket搞混淆了吧,要么两端都用socket,要用http的话,服务器端也要是跟http相关的啊,比如servlet.
不会,帮忙顶有分么
mark!
你的程序应该和http协议无关啊,你先不管它什么http协议,先直接写client和server传一个文件试试。成了再改进。
我刚才调试了一下,你如果想这样做也可以,就是在服务器端接收的时候要把http请求的信息去掉,"POST / HTTP/1.1
Content-type: application/octet-stream
Content-length: 121
Cache-Control: no-cache
Pragma: no-cache
User-Agent: Java/1.4.2_08
Host: 127.0.0.1:9999
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive" 这段信息看到了吗? 你为什么把这段信息也直接放到ObjectInputStream里面去?? 这样怎么会不出错呢?只有头信息后面才是正文. 所有要在buf中找出正文信息.
从Content-length: 121可以看出来,正文内容有121个byte. 而前面System.out.println("len=" + len);打印出来的信息是len=379,所以buf中379-121=258个byte是头信息,改写后的程序:
在int len = input.read(buf);下一行加:
byte[] test = new byte[121];
int k = 0;
for (int i = 258; i < 379;)
{
test[k++] = buf[i++];
}
再把出错那行该成:
oins = new ObjectInputStream(new ByteArrayInputStream(test));
这样就对了.
两边都用socket,使用tcp协议就是了,不要管http
楼上正解。
传过来的信息包含HTTP头信息。
需要把它去掉。。
从中截取出自己需要的那部分信息。。
如果用socket-httpserver, 需要生成或解析http头信息. 最好使用java 的webclient api来实现提交即可
bblood(blueblood) 你跟我的想法一样,我试一下,看看能否成功。上面各们兄弟,不是我想搞这么麻烦,是上司要这样做,本来服务器想直接用SERVLET搞的,可上司说太简单了,要自己写一个HTTP服务。客户端也只能用HTTP的协议啊,因为公司的限制,只可以用HTTP啊,不然都用SOCKET传输或FTP传输,多方便,也不用写,网上一大把代码。不过还是得感谢大家。非常的谢谢大家。
bblood(blueblood)的方法 好像文件内容还是没有取对,奇怪了
不会的吧,我在自己机器上调过的,可以通过,可能是我不是跟原来程序一模一样的,所以数字方面有出入:我这里Content-length: 121,原来程序肯定不是的,你再查查.还有我这里打印出来的信息是len=379,原来程序也不一定相等,所以还是要根据具体情况去推算该取哪一段,可能你说的好像文件内容还是没有取对是因为少取了或多取了一两位
Server:
package studyjava.httpstream;
import java.net.*;
import java.io.*;
public class Server {
public static void main(String[] args) {
run();
}
public static void run() {
ServerSocket server_socket;
try {
int port = Integer.parseInt("9999");
server_socket = new ServerSocket(port);
// sm.setMsg("服务器已经启动:开始监听"+port+"端口");
System.out.println("服务器已经启动:开始监听" + port + "端口");
while (true) {
Socket socket = server_socket.accept();
System.out.println("New Connection accepted:"
+ socket.getInetAddress() + ":" + socket.getPort());
// 创建分线程;
// sm.setMsg("服务器接收到新连接!");
try {
httpRequestHandler request = new httpRequestHandler(socket);
Thread thread = new Thread(request);
thread.start();
} catch (Exception ex) {
ex.printStackTrace();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
class httpRequestHandler implements Runnable {
final static String CRLF = "/r/n";
Socket socket;
InputStream input;
PrintStream output;
BufferedReader br;
ObjectInputStream in;
public httpRequestHandler(Socket ssocket) throws Exception {
this.socket = ssocket;
}
public void run() {
try {
// in = new ObjectInputStream(ssocket.getInputStream());
System.out.println("begin socket.getInputStream()");
input = socket.getInputStream();
byte[] buf = new byte[2048];
int len = input.read(buf);
byte[] test = new byte[121];
int k = 0;
for (int i = 258; i < len;)
{
//System.out.println(buf[i] + " index=" + i);
test[k++] = buf[i++];
}
System.out.println("len=" + len);
ObjectInputStream oins = null;
String tempstr = new String(test);
String tempstr2 = new String(buf);
//System.out.println(tempstr);
System.out.println(tempstr2);
oins = new ObjectInputStream(new ByteArrayInputStream(test)); // 程序运行到此处出错。请大家帮忙。
System.out.println("begin read Msg");
ObjectMsg msg = (ObjectMsg) oins.readObject();
System.out.println("getSendMsg: " + msg.getSendMsg());
oins.close();
System.out.println("end socket.getInputStream()");
ObjectOutputStream outs = new ObjectOutputStream(socket.getOutputStream());
msg.setName("hello");
outs.writeObject(msg);
outs.close();
input.close();
socket.close();
// in=new ObjectInputStream(input);
System.out.println("socket.getInputStream()ok");
} catch (Exception ex) {
System.out.println("socket.getInputStream()出错:" + ex.getMessage());
ex.printStackTrace();
}
}
}
Client:
package studyjava.httpstream;
import java.io.*;
import java.net.*;
public class Client {
public static void main(String[] args) {
SendFile("", "");
}
public static String SendFile(String filePath, String filename) {
String retM = "";
String httpUrl = "http://127.0.0.1:9999";
BufferedReader br = null;
URL myURL = null;
HttpURLConnection myHttpCon = null;
try {
// 准备连接URL;
myURL = new URL(httpUrl);
myHttpCon = (HttpURLConnection) myURL.openConnection();
myHttpCon.setUseCaches(false);
myHttpCon.setDoOutput(true);
myHttpCon.setDoInput(true);
// myHttpCon.setRequestMethod("POST");
// myHttpCon.connect();
// 输出流;
ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(byteOut);
// 信息;
ObjectMsg outMsg = new ObjectMsg();
// byte[] buffer=new byte[2056];
// FileInputStream filein=new FileInputStream(filePath);
// filein.read(buffer,0,2056);
outMsg.setSendMsg("it is test,i want to success,please help me!thanks a lot.");
outMsg.setId(1);
outMsg.setName(filename);
outMsg.setSendMsg("test,success");
// outMsg.setValue(buffer);
// 输出到缓冲区;
out.writeObject(outMsg);
out.flush();
out.close();
byte[] buf = byteOut.toByteArray();
// 输出信息到服务器;
myHttpCon.setRequestProperty("Content-type",
"application/octet-stream");
myHttpCon.setRequestProperty("Content-length", "" + buf.length);
DataOutputStream dataOut = new DataOutputStream(myHttpCon
.getOutputStream());
dataOut.write(buf);
dataOut.flush();
dataOut.close();
// 响应消息流;
ObjectInputStream in = new ObjectInputStream(myHttpCon
.getInputStream());
// 接收响应对象;
ObjectMsg msgOut = (ObjectMsg) in.readObject();
System.out.println(msgOut.getName());
in.close();
retM = "ok";
} catch (Exception ex) {
retM = "error";
ex.printStackTrace();
}
return retM;
}
}
谢谢楼上兄弟,我后来换了另一种方式,发现HTTP头信息和文件流数据是分开的.
我会好好试用一下这个方法.