2011-11-12 82 views
0

我編寫客戶端 - 服務器應用程序。客戶端在Android上,普通Java上的服務器上。我希望客戶端與服務器建立連接,然後向他發送一些文件,然後服務器在服務器光盤上寫入此文件,然後向客戶端發送另一個文件。現在客戶端建立連接然後發送文件到服務器,但這裏開始出現問題。當我想要服務器發送文件給客戶端時,我得到「套接字關閉」異常。android和套接字

這裏是我的代碼:

服務器:

public class ThreadHandler implements Runnable 
{ 
public ThreadHandler(Socket i) 
{ 
    sk = i; 
} 

public void run() 
{ 
    try 
    { 
     File file = getFile(); 
     ParseData data = parseXML(file); 

     if(data.getEvent().equals("registration")) 
     { 
      sendRegistrationResponse(); 
     } 
    } 
    catch(Exception e) 
    { 
     e.printStackTrace(); 
    } 
} 

public File getFile() throws Exception 
{ 
    File file=null; 

    InputStream input = sk.getInputStream(); 

    file = new File("C://protocolFile/" + "temp.xml"); 
    FileOutputStream out = new FileOutputStream(file); 

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

    int bytesReceived = 0; 

    while((bytesReceived = input.read(buffer))>0) { 
     out.write(buffer,0,bytesReceived); 
    } 

    input.close(); 
    input = null; 
    out.flush(); 
    out.close(); 
    out = null; 
    System.gc(); 

    return file; 
} 

public void sendRegistrationResponse() throws Exception 
{ 
    String fileName = createRegistrationResponseXML(); 
    sendToApp(fileName); 
} 

public void sendToApp(String fileName) throws Exception 
{ 
    OutputStream output = sk.getOutputStream();  

    FileInputStream fileInputStream = new FileInputStream(fileName); 
    byte[] buffer = new byte[sk.getSendBufferSize()]; 
    int bytesRead = 0; 

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

    output.close(); 
    fileInputStream.close(); 
} 

} 

客戶端:

public class AndroidProtokolActivity extends Activity { 

private File directory; 

XmlSerializer serializer = Xml.newSerializer(); 
StringWriter writer=new StringWriter();; 

Socket sk; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 
    directory = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "protocol"); 
    directory.mkdirs(); 
} 

public void fun(View view) 
{ 
    Log.i("======", "fun=============="); 
    try 
    { 
     sk = new Socket("55.555.555.555", 5555); 

     String registrationFile = createRegistrationXML(serializer); 
     sendToServer(registrationFile,sk); 
     getRegistrationXML(); 
    } 
    catch(Exception e) 
    { 
     e.printStackTrace(); 
    } 
} 

public void sendToServer(String file, Socket sk) throws Exception 
{ 
    Log.i("======", "sendToServer=============="); 
    OutputStream output = sk.getOutputStream();  

    String pathToOurFile = directory + File.separator + file; 

    FileInputStream fileInputStream = new FileInputStream(pathToOurFile); 
    byte[] buffer = new byte[sk.getSendBufferSize()]; 
    int bytesRead = 0; 

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

    output.close(); 
    fileInputStream.close(); 
} 

public File getRegistrationXML() throws Exception 
{ 
    Log.i("======", "getRegistrationXML=============="); 
    File file=null; 

    InputStream input = sk.getInputStream(); 

    file = new File(directory, "rejestracjaOdpowiedz.xml"); 
    FileOutputStream out = new FileOutputStream(file); 

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

    int bytesReceived = 0; 

    while((bytesReceived = input.read(buffer))>0) { 
     out.write(buffer,0,bytesReceived); 
    } 

    input.close(); 
    input = null; 
    out.flush(); 
    out.close(); 
    out = null; 
    System.gc(); 

    return file; 
} 
} 

我從這個代碼削減創建XML文件的功能。我在「OutputStream output = sk.getOutputStream();」上得到「java.net.SocketException:Socket is closed」在服務器端的函數「sendToApp」和「InputStream input = sk.getInputStream();」上的「java.net.SocketException:Socket is closed」在客戶端的函數「getRegistrationXML」中的「getRegistrationXML」行中。我試圖找出什麼是錯的,但我沒有任何想法。你們中的任何人都知道這個代碼是什麼?謝謝你的幫助。

編輯:

此代碼展示如何創建XML文件:

public String createRegistrationXML(XmlSerializer serializer) throws Exception 
{ 
    Log.i("======", "createRegistrationXML=============="); 
    XmlSerializer serializer = Xml.newSerializer(); 
    writer = new StringWriter(); 
    serializer.setOutput(writer); 

    serializer.startDocument("UTF-8", true); 
     serializer.startTag("", XMLTag); 
      serializer.startTag("", eventTag); 
       serializer.text(REGISTRATIONEVENT); 
      serializer.endTag("", eventTag); 
     serializer.endTag("", XMLTag); 
    serializer.endDocument(); 

    File outputFile = new File(directory, "file.xml"); 
    FileOutputStream fos = new FileOutputStream(outputFile); 
    OutputStreamWriter osw = new OutputStreamWriter(fos); 
    osw.write(writer.toString()); 
    osw.flush(); 
    osw.close(); 

    return "file.xml"; 
} 

回答

1

儘量不要單獨關閉套接字的輸入和輸出流。全部完成後,關閉插座

+0

予刪除流()(=與BytesReceived input.read(緩衝器)> 0)的每個靠近函數,然後服務器現在停留在」,而{ \t \t \t out.write(緩衝液,0,與BytesReceived); \t \t }「on」getFile「函數,但客戶端卡在函數」getRegistrationXML「中。它看起來像(bytesReceived = input.read(buffer))總是大於0.請檢查我在第一篇文章中如何在編輯中創建XML文件,也許存在我的問題 – klemens

+1

這是正確的:socket讀*操作會阻塞直到收到數據,它不知道什麼時候收到所有的數據,你可能需要一種方法將數據的末尾發送給接收器,這樣它就會停止讀取並開始發送 – JimmyB

+0

我注意到當我有線路輸出時。關閉();「在」sendToServer「 在客戶端服務器dont stuce。你知道它的意思嗎? – klemens