2012-10-08 2 views
0

서버에서 클라이언트로 파일을 보내는데 문제가 발생했습니다. 서버에서 클라이언트로 동일한 파일을 두 개의 다른 파일로 보낼 수 없습니다. 대신 첫 번째 파일의 끝에 추가됩니다. 어떤 도움을 주시면 감사하겠습니다.Java - 두 번째 파일에 쓸 수 없음

편집 : 코드를 수정했습니다. 나는 2 개의 함수 'sendfile'과 'recievefile'로 작업을 보내고받는 모듈을 모듈화했다. 지금 얻고있는 오류는 소켓이 두 번째 호출 후에 sendfile 및 recievefile 함수에서 닫혀 있다는 것입니다. 하지만 내가 닫고있는 것은 파일과 출력 및 입력 스트림입니다. 아마도 그 스트림을 닫으면 소켓도 닫힙니다 ...? 어쨌든, 나는 입력 및 출력 스트림을 닫지 않으려 고 노력했으며 어떤 일이 일어나는가 - 1) 아무것도 대상 파일로 전송되지 않습니다. 그래서 나는 서버 끝에 무작위로 생성 된 파일을 얻는다. 2) 두 번째 파일도 생성되지 않습니다. 큰.

평소와 같이 도움이된다면 도움이됩니다.

서버 :

package com.http.server; 
import java.io.*; 
import java.net.*; 

public class Server 
{ 
    public static void main(String args[])throws Exception 
    { 
     System.out.println("Server running..."); 

     /* Listen on port 5555 */ 

     ServerSocket server = new ServerSocket(5555); 

     /* Accept the sk */ 

     Socket sk = server.accept(); 

     System.out.println("Server accepted client"); 


     BufferedReader inReader = new BufferedReader(new InputStreamReader(sk.getInputStream())); 
     BufferedWriter outReader = new BufferedWriter(new OutputStreamWriter(sk.getOutputStream())); 

     /* Read the filename */ 
     String serverlocation = "C:/Users/Arjun/Desktop/CNW model/HTTP Website/"; 
     String filename = serverlocation + inReader.readLine(); 
     if (!filename.equals("")){ 

      /* Reply back to client with READY status */ 

      outReader.write("READY\n"); 
      outReader.flush();   
     } 

     sendfile(sk, filename); 
     sendfile(sk, filename); 

     outReader.close(); 
     inReader.close(); 


     sk.close(); 
     server.close(); 

    } 

    public static void sendfile(Socket sk, String filename) 
    { 
     try{ 

      OutputStream output = sk.getOutputStream(); 

     FileInputStream file = new FileInputStream(filename); 

     byte[] buffer = new byte[sk.getSendBufferSize()]; 

     int bytesRead = 0; 

     while((bytesRead = file.read(buffer))>0) 
     { 
      output.write(buffer,0,bytesRead); 
     } 

     file.close(); 
     output.close(); 
    } 
     catch (Exception ex){ 
      System.out.println(ex); 
     } 
     } 





    } 

클라이언트 : 사용자가 파일을 보낼 때

package com.http.client; 
import javax.swing.*; 
import java.awt.*; 
import java.awt.event.*; 
import java.net.*; 
import java.io.*; 

public class Client extends JFrame implements ActionListener { 

    /** 
    * 
    */ 
    private static final long serialVersionUID = 1L; 
    private JTextField txtFile; 

    public static void main(String args[]){ 

     /* Create and display the client form */ 

     Client clientForm = new Client(); 
     clientForm.Display(); 
    } 

    public void Display(){ 

     JFrame frame = new JFrame(); 
     frame.setTitle("Client"); 

     FlowLayout layout = new FlowLayout(); 
     layout.setAlignment(FlowLayout.LEFT); 

     JLabel lblFile = new JLabel("URL:"); 

     txtFile = new JTextField(); 
     txtFile.setPreferredSize(new Dimension(150,30)); 

     JButton btnTransfer = new JButton("Get"); 
     btnTransfer.addActionListener(this); 

     JPanel mainPanel = new JPanel(); 
     mainPanel.setLayout(layout); 
     mainPanel.add(lblFile); 
     mainPanel.add(txtFile); 
     mainPanel.add(btnTransfer); 

     frame.getContentPane().add(mainPanel); 
     frame.pack(); 
     frame.setVisible(true); 
    } 

    public void actionPerformed(ActionEvent e) { 

     /* File Open Dialog box allows the user to select a file */ 

     String filename=txtFile.getText(); 

     try{ 

      /* Try to connect to the server on localhost, port 5555 */ 

      Socket sk = new Socket("localhost", 5555); 


      /* Send filename to server */ 

      OutputStreamWriter outreader = new OutputStreamWriter(sk.getOutputStream()); 
      outreader.write(filename + "\n"); 
      outreader.flush(); 

      /* Get response from server */ 

      BufferedReader inReader = new BufferedReader(new InputStreamReader(sk.getInputStream())); 

      String serverStatus = inReader.readLine(); // Read the first line 
      /* If server is ready, receive the file */ 

      while (!serverStatus.equals("READY")){} 

       /* Create a new file in the tmp directory using the filename */ 

       recievefile(sk,filename); 
       recievefile(sk,"xx"+filename); 


       JOptionPane.showMessageDialog(this, "Transfer complete"); 


       inReader.close(); 
       outreader.close(); 
      sk.close(); 

     } 
     catch (Exception ex){ 
      /* Catch any errors */ 
      JOptionPane.showMessageDialog(this, ex.getMessage()); 
      System.out.println(ex); 
     } 
    } 

    public void recievefile(Socket sk, String filename) 
    { 
     try{ 

      InputStream input = sk.getInputStream(); 

     FileOutputStream wr = new FileOutputStream(new File("C:/tmp/" + new File(filename).getName())); 

     byte[] buffer = new byte[sk.getReceiveBufferSize()]; 
     int bytesReceived = 0; 

     while((bytesReceived = input.read(buffer))>0) 
     { 
      /* Write to the file */ 
      wr.write(buffer,0,bytesReceived); 
     } 
     wr.close(); 
     input.close(); 

    } 
     catch (Exception ex){ 
      /* Catch any errors */ 
      JOptionPane.showMessageDialog(this, ex.getMessage()); 
      System.out.println(ex); 
     } 

} 




} 
+1

새 파일은 열리지 만 새 스트림은 열지 않습니다. 두 파일을 같은 스트림을 따라 보내므로 클라이언트가 파일의 끝까지 도달하지 못한다고 생각합니다. – Chris

+0

파일 이름이 실제로 "blah.htm"이 아닌 것은 확실합니까? – Wug

+0

파일 이름은 실제로 "blah.htm"이 아닙니다. 이 코드의 목적은 요청 된 파일을 서버에서 전송하는 것입니다. 그러나 나는 그것을 두 번 옮긴다. 일단 appriopriate 파일에 한 번 더미 파일에 a.k.a blah.htm –

답변

5

, 당신은 너무 클라이언트가 볼 방법 이잖아 뒤에 다른 하나를 추가한다.

클라이언트가 한 파일 읽기를 중지하고 두 번째 파일 읽기를 시작할 때 알려야합니다.

가장 간단한 방법은 파일 앞에 파일의 길이를 보내고 데이터 양보다 정확하게 읽는 것입니다.

진술 : 바이너리와 텍스트 스트림을 함께 사용할 수 없습니다. 이것은 혼란을 야기 할 가능성이 더 큽니다. 귀하의 경우에는 바이너리를 보내서 DataInputStream 및 DataOutputStream으로 모든 바이너리를 작성해야합니다.


나는 마음에 두었던 것이 있습니다.

public static void sendFile(DataOutput out, String filename) throws IOException { 
    FileInputStream fis = new FileInputStream(filename); 
    byte[] bytes = new byte[8192]; 
    try { 
     long size = fis.getChannel().size(); 
     out.writeLong(size); 
     for (int len; (len = fis.read(bytes, 0, (int) Math.min(bytes.length, size))) > 0;) { 
      out.write(bytes, 0, len); 
      size -= len; 
     } 
     assert size == 0; 
    } finally { 
     fis.close(); 
    } 
} 

public void receiveFile(DataInput in, String filename) throws IOException { 
    long size = in.readLong(); 
    FileOutputStream fos = new FileOutputStream(filename); 
    byte[] bytes = new byte[8192]; 
    try { 
     for (int len; (len = (int) Math.min(size, bytes.length)) > 0;) { 
      in.readFully(bytes, 0, len); 
      fos.write(bytes, 0, len); 
      size -= len; 
     } 
    } finally { 
     fos.close(); 
    } 
} 
+0

흠, 나는 완전히 이해하지 않는다. 나는 이것을 서버 쪽에서 사용했다 : while (bytesRead = file.read (buffer))> 0) { output.write (buffer, 0, bytesRead); } 나는 또한 소켓 스트림을 받아 들일 수있는 동등한 제어 구조를 사용했으며 클라이언트는 적절한 바이트 수가 기록 된 후에 파일을 닫으므로 다음 파일을 멈추고 시작할 때를 알아야합니다. ... 더 이상의 제안? 아니면 좀 더 명쾌합니까? –

+0

또 다른 이유는 내가 어떤 파일 형식에 대해서도 같은 문제가있는 것 같기 때문입니다. ( –

+0

클라이언트가 서버 측에서 파일을 닫았다는 것을 알지 못합니다. –

관련 문제