2011-06-30 207 views
4

我试图从客户端向服务器发送文件。服务器接收文件,然后向客户端发送确认消息。发送文件,然后通过套接字发送消息

我的问题是客户端在等待确认时变得无响应。

服务器:

import java.net.*; 
import java.io.*; 

public class Server { 
public static void main(String args[]) throws IOException { 
     int port = 1234; 
    ServerSocket server_socket; 

    server_socket = new ServerSocket(port); 
    System.out.println("Server waiting for client on port " 
      + server_socket.getLocalPort()); 
    // server infinite loop 
    while (true) { 
     Socket socket = server_socket.accept(); 
     System.out.println("New connection accepted " 
       + socket.getInetAddress() + ":" + socket.getPort()); 
    try { 
       byte[] b = new byte[1024]; 
       int len = 0; 
       int bytcount = 1024; 
       String FileName = "C:\\test\\java\\tmp\\sentfile.pdf"; 
       FileOutputStream inFile = new FileOutputStream(FileName); 
       InputStream is = socket.getInputStream(); 
       BufferedInputStream in2 = new BufferedInputStream(is, 1024); 
       while ((len = in2.read(b, 0, 1024)) != -1) { 
        bytcount = bytcount + 1024; 
       inFile.write(b, 0, len); 
       } 
       System.out.println("Bytes Writen : " + bytcount); 

       //Sending the response back to the client. 
       ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream()); 
       oos.flush(); 
       oos.writeObject("ok"); 
       System.out.println("Message sent to the client is "+"ok"); 

       in2.close(); 
       inFile.close(); 
      } catch (IOException e) { 
     System.out.println("Unable to open file" + e); 
     return; 
    } 
    socket.close(); 
    System.out.println("Connection closed by client"); 
     } 
} 
} 

客户:

import java.net.*; 
import java.io.*; 

public class Client { 
    public static void main(String[] args) throws UnknownHostException, 
     IOException, ClassNotFoundException { 

     int port = 1234; 
    Socket socket = null; 

    // connect to server 
    socket = new Socket("127.0.0.1", port); 

    try { 
      byte[] buf = new byte[1024]; 
      OutputStream os = socket.getOutputStream(); 
      BufferedOutputStream out = new BufferedOutputStream(os, 1024); 
      String file = "C:\\test\\java\\client\\source.pdf"; 
      FileInputStream in = new FileInputStream(file); 
      int i = 0; 
      int bytecount = 1024; 
      while ((i = in.read(buf, 0, 1024)) != -1) { 
       bytecount = bytecount + 1024; 
      out.write(buf, 0, i); 
      out.flush(); 
      } 
      System.out.println("Bytes Sent :" + bytecount); 

      ObjectInputStream ois = new ObjectInputStream(socket.getInputStream()); 
      String confirmation = (String) ois.readObject(); 
      System.out.println("from server : " + confirmation); 

      out.close(); 
      in.close(); 
    } catch (IOException e) { 
    System.out.println(e); 
    } 
    socket.close(); 
} 
} 
+0

可能你不会从服务器端刷新输出流吗?你看到这条消息:'发送给客户端的消息是否可以'? – Lynch

+0

将对无响应部分发表评论。如果客户端正在等待响应(阅读响应),那么我想它会没有响应。您是否考虑过在单独的线程中提出请求?在客户端的 – Andreas

+0

,它在“Bytes Sent:..”之后被阻塞。 如果我评论第一部分,它是工作。 如果我对第二部分发表评论,它正在工作。 两者都不行。 – ophelie88

回答

7

下面是完整的工作示例。服务器:

package so6540787; 

import java.io.BufferedInputStream; 
import java.io.File; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.ObjectOutputStream; 
import java.net.ServerSocket; 
import java.net.Socket; 

public class Server { 

    private final Socket socket; 

    public Server(Socket socket) { 
    this.socket = socket; 
    } 

    public void receiveFile(File file) throws IOException { 
    byte[] b = new byte[1024]; 
    int len = 0; 
    int bytcount = 1024; 
    FileOutputStream inFile = new FileOutputStream(file); 
    InputStream is = socket.getInputStream(); 
    BufferedInputStream in2 = new BufferedInputStream(is, 1024); 
    while ((len = in2.read(b, 0, 1024)) != -1) { 
     bytcount = bytcount + 1024; 
     inFile.write(b, 0, len); 
    } 
    System.out.println("Bytes Writen : " + bytcount); 

    // Sending the response back to the client. 
    ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream()); 
    oos.flush(); 
    oos.writeObject("ok"); 
    System.out.println("Message sent to the client is " + "ok"); 

    in2.close(); 
    inFile.close(); 
    } 

    public static void main(String[] args) throws IOException { 
    ServerSocket listen = new ServerSocket(10000, 1); 
    Socket socket = listen.accept(); 
    Server server = new Server(socket); 
    server.receiveFile(new File("c:/received.pdf")); 
    } 
} 

而且客户端:

package so6540787; 

import java.io.BufferedOutputStream; 
import java.io.File; 
import java.io.FileInputStream; 
import java.io.IOException; 
import java.io.ObjectInputStream; 
import java.io.OutputStream; 
import java.net.Socket; 

public class Client { 

    private final Socket socket; 

    public Client(Socket socket) { 
    this.socket = socket; 
    } 

    public void sendFile(File file) throws IOException, ClassNotFoundException { 
    byte[] buf = new byte[1024]; 
    OutputStream os = socket.getOutputStream(); 
    BufferedOutputStream out = new BufferedOutputStream(os, 1024); 
    FileInputStream in = new FileInputStream(file); 
    int i = 0; 
    int bytecount = 1024; 
    while ((i = in.read(buf, 0, 1024)) != -1) { 
     bytecount = bytecount + 1024; 
     out.write(buf, 0, i); 
     out.flush(); 
    } 
    socket.shutdownOutput(); /* important */ 
    System.out.println("Bytes Sent :" + bytecount); 

    ObjectInputStream ois = new ObjectInputStream(socket.getInputStream()); 
    ois.skip(Long.MAX_VALUE); 
    String confirmation = (String) ois.readObject(); 
    System.out.println("from server : " + confirmation); 

    out.close(); 
    in.close(); 
    } 

    public static void main(String[] args) throws IOException, ClassNotFoundException { 
    Client client = new Client(new Socket("localhost", 10000)); 
    client.sendFile(new File("c:/tobesent.pdf")); 
    } 
} 

你缺少的行是 “socket.shutdownOutput()”。如果将该行保留,服务器将永远不会从read调用中看到文件结束标记-1

请修复您计算已发送字节的方式。您应该真正从0开始而不是1024开始,并且只能通过实际读取的字节数增加该计数器。

+0

谢谢。 我认为这是类似的东西,清除插座。我尝试冲洗,重新放置,关闭等。 – ophelie88

+0

所有的确认代码都是多余的和不必要的。 –

+0

在目前的形式,它真的是多余的。但是,只要服务器发回一些信息(数据已存储的文件名,如果磁盘已满,则为错误代码),该协议就变得非常有用。例如,如果服务器刚刚关闭套接字而不先发送“ok”,客户端如何知道最后一个字节已成功写入? –

0

使用HTTP!它专为这种类型的问题而设计。有大量HTTP客户端和服务器库可供Java免费使用。

+2

不应该这是一个评论? – pqsk