2011-11-12 8 views
0

私はクライアントとサーバーのアプリケーションを書いています。クライアントはアンドロイド上にあり、サーバーはプレーンJava上にあります。私はクライアントがサーバーとの接続を確立し、次にファイルを送信してから、サーバーがこのファイルをサーバーディスクに書き込んで、クライアントに別のファイルを送信します。今のところ、クライアントは接続してからサーバーにファイルを送信しますが、ここで問題が発生します。サーバーにクライアントにファイルを送信したいとき、私は「ソケットが近い」という例外を受け取ります。アンドロイドとソケット

は、ここに私のコードです:

サーバー:

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ファイルの関数を作成するこのコードからカット。私は "java.net.SocketException:ソケットが閉じている"という行を "OutputStream output = sk.getOutputStream();"サーバー側で "sendToApp"関数で "InputStream input = sk.getInputStream();"という行で "java.net.SocketException:Socket is closed"クライアント側の関数 "getRegistrationXML"の "getRegistrationXML"行に記述します。私は間違っていることを見つけようとしますが、私は考えていません。このコードで何が起きているのか分かっていますか?助けてくれてありがとう。

EDIT:

このコードのショー、私は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

Iは、ストリーム上のすべての密接funcionを削除し、現在「しばらく((は、bytesreceived = input.read(バッファ))> 0){ \t \t \t out.write(バッファ、0、は、bytesreceived)で立ち往生サーバ; \t \t } "getFile"関数で、クライアントは "getRegistrationXML"関数でスタックしました。そのように見える(bytesReceived = input.read(buffer)は常に0です。)私の最初の投稿でXMLファイルを編集する方法を確認してください。問題があるかもしれません。 – klemens

+1

これは正しいです。データが受信されるまでブロックしますすべてのデータがいつ受信されるかはわかりませんが、データの終わりを受信者に知らせる方法が必要なので、読み込みを停止して送信を開始します。 – JimmyB

+0

"出力" – klemens