我需要一个ClientSocket和一个ServerSocket,在两者之间进行传送文件,具体要求是先是Client传送到Server端,Server处理完数据后再传送到Client端.我现在的程序Client端能传送到Server过去,但是Server传送不回来,每次Client接收的时候提示:Socket Closeed,但是我人为的延迟也收不回来,哪位高手请指点一二..不胜感激
调试欢乐多
DataOutputStream dos = null; DataInputStream diss = null ;
DataOutputStream doss = null ;
Socket ClientSocket = null;
String strIp = "127.0.0.1" ;
String strPort = "8001" ;
try {
ClientSocket = new Socket(InetAddress.getByName(strIp), Integer.parseInt(strPort));
ClientSocket.setSoTimeout(60000);
//创建Socket的输入输出流
OutputStream ops = ClientSocket.getOutputStream();
InputStream ips = ClientSocket.getInputStream(); // 为发送准备
dis = new DataInputStream(new BufferedInputStream(new FileInputStream(zipfile)));
dos = new DataOutputStream(new BufferedOutputStream(ops));
File file = new File(zipfile);
int iSize = Integer.parseInt(String.valueOf(file.length()));
byte[] buf = new byte[iSize];
while ((dis.read(buf)) != -1) {
dos.write(buf, 0, buf.length);
}
System.out.println("客户端传输完毕");
dos.close(); // 为接收准备
BufferedInputStream br = new BufferedInputStream(ips);
//以DataInputStream来包装字节缓冲输入流
diss = new DataInputStream(br);
//以DataOutputStream来包装字节缓冲输出流
doss = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(zipAnsw)));
byte[] bufr = new byte[1024];
//网络传输都是以字节的方式传递的
while ((diss.read(bufr,0,bufr.length)) != -1) {[red]每次都是在这个地方就异常,提示Socket Closed[/red]
//一边读,一边写
doss.write(bufr, 0, bufr.length);
}
System.out.println("fasdjlsa:"+ClientSocket.isConnected());
System.out.println("客户端接收完毕");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
dis.close();
dos.close();
diss.close();
doss.close();
ClientSocket.close();
} catch (IOException ex) {ex.printStackTrace();}
}
服务端的程序是:
首先建立一个阻塞SocketServer:import java.util.zip.*;
import java.io.IOException;
import java.net.Socket;
import java.net.ServerSocket;
import java.io.*;public class Server {
public Server() {
} public static void main(String[] a) {
Socket s = null;
ServerSocket Server = null;
String file = "D:\\Socket\\Server\\question.zip";
try {
//判断是否在命令行的方式传递了输出文件的文件名
Server = new ServerSocket(8001);
System.out.println("Server Started ...");
while (true) {
//接受客户端的请求发送文件,没有请求则阻塞
s = Server.accept();
//以重新启动一个线程的方式,取得客户端发送的文件
new Thread(new Servicer(s, file)).start();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
s.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
然后处理程序为:import java.io.*;
import java.net.Socket;public class Servicer implements Runnable {
public Servicer() {
} Socket server = null;
String fileName = null;
String ClientPort = "0000";
String IP = "127.0.0.1" ;
String PORT = "0000" ;
//传递文件名和Socket
Servicer(Socket s, String fileName) {
this.server = s;
this.fileName = fileName; } public void run() {
DataInputStream dis = null;
DataOutputStream dos = null; DataInputStream disa = null;
DataOutputStream dosa = null; //创建Socket的输入输出流
try {
this.IP = server.getInetAddress().toString() ;
this.PORT = String.valueOf(server.getPort()) ;
System.out.println("地址是:" + this.IP);
System.out.println("端口是:" + this.PORT);
InputStream ips = server.getInputStream();
OutputStream ops = server.getOutputStream();
BufferedInputStream br = new BufferedInputStream(ips);
//以DataInputStream来包装字节缓冲输入流
dis = new DataInputStream(br);
//以DataOutputStream来包装字节缓冲输出流
dos = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(fileName)));
byte[] bufr = new byte[1024];
//网络传输都是以字节的方式传递的
while ((dis.read(bufr)) != -1) {
//一边读,一边写
dos.write(bufr, 0, bufr.length);
}
System.out.println("服务器端接收完毕");
dis.close();
dos.close();
try {
String zipfile = "D:\\Socket\\Server\\answer.zip"; dis = new DataInputStream(new BufferedInputStream(new FileInputStream(zipfile)));
dos = new DataOutputStream(new BufferedOutputStream(ops));
File file = new File(zipfile);
int iSize = Integer.parseInt(String.valueOf(file.length()));
byte[] buf = new byte[iSize];
while ((dis.read(buf)) != -1) {
dos.write(buf, 0, buf.length);
}
dos.close(); System.out.println("服务器端传输完毕");
} catch (IOException ex2) {
ex2.printStackTrace();
}
disa.close();
dosa.close();
Thread.sleep(2000);
} catch (FileNotFoundException fe) {
fe.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
dis.close();
dos.close();
disa.close();
dosa.close();
server.close();
} catch (IOException ex) {}
}
}}
请指教~~
boolean FLAG = true;
public void run()
{
建立连接
...
while(FlAG)
{
打开流
...
数据传输(接收)
...
关闭流
...
sleep(2000);
}
关闭连接
...
}
大概就这样,你可能有一个理解错误是觉得线程一旦启动,只要我们不关闭,它会一直存在并等待,其实不是这样,线程执行完run()中的代码后就会自动结束,所以只要在你的客户和服务端都加上循环,就OK了
Vector clientList = new Vector();
while (true)
{
//接受客户端的请求发送文件,没有请求则阻塞
s = Server.accept();
//以重新启动一个线程的方式,取得客户端发送的文件
Thread currentThread = new Thread(new Servicer(s, file));
currentThread.start();
clientList.add(currentThread);
}
这样保证一个客户端有一个相应的服务线程为它服务,不会导致客户端发送完以后没有dos.close();,客户端和服务器端就死锁掉,服务器想干什么就到clientList找到相应的客户连接操作就OK了
感谢炮炮兄:不过这样子和我的程序有什么区别吗,不都是一样的吗,来了一个连接就启动一个线程,我现在的情况是在一个线程启动的情况下都不能传输文件(能传过去,不能传回来),在while ((dis.read(bufr)) != -1) {
时会阻塞掉,麻烦你再看看.
client发送File到server建立一个连接,传送完,关闭连接
server处理文件,处理完后就新建一个连接到client,
client启动一个socket来接受
接收后关闭
while (true)
{
//接受客户端的请求发送文件,没有请求则阻塞
s = Server.accept();
//以重新启动一个线程的方式,取得客户端发送的文件
new Thread(new Servicer(s, file)).start();
}
当有一个连接请求的时候,都会生成一个新的Servicer对象,而原来的对象则被销毁,所以,应该在生成新对象的时候,把它保存到向量中,新的对象产生了,而原来的对象仍然生存,就可以完成一对多的服务;然后说流的问题,我不确定,因为没有这么做过,我建议你写一些简单的协议(姑且称为协议),在文件传输的时候就知道了文件的长度等信息,直接读指定长度,关于那个为什么不行我再查查书吧
那我client需要在WebLogic上运行,我就不能再启动ServerSocket了吧,可是如果我建立一个Socket对象的话,算是一个客户端,没法连接吧,请指点.