RT我做的是Android客户端(好吧,我还是想在Java SE板块来问,因为问题出在Java的Socket上)与C#编写的服务器端进行数据交互
单独测试Android发送、C#接收,或者,C#发送、Android接收,都没问题现在我想这么做:
(1)Android发送一组数据,由C#来接收
(2)C#处理之后,发送一组数据返回给Android
(3)Android接收之后,显示给用户现在(1),(2)都正常,问题出在(3)
我的Android端的流程是这样的:
<1>获得socket实例的OutputStream对象实例sendStream = socket.getOutputStream();
<2>用sendStream 发送byte[]给C#端
<3>sendStream 发送完毕之后关闭这个sendStream ,sendStream.close();
<4>获得socket实例的InputStream对象实例,receiveStream=socket.getInputStream();就在第<4>步出问题了,显示Socket is closed
但我并没有关socket,而且就在我receiveStream=socket.getInputStream();之前我还打印了socket的状态的:
Log.d(TAG,"socket.isClosed()="+socket.isClosed());
Log.d(TAG,"socket.isInputShutdown()="+socket.isInputShutdown());
receiveStream=socket.getInputStream();
打印结果如下:
05-06 15:05:59.341: DEBUG/LZ(5963): socket.isClosed()=false
05-06 15:05:59.341: DEBUG/LZ(5963): socket.isInputShutdown()=false
05-06 15:05:59.341: ERROR/LZ(5963): Socket is closed
05-06 15:05:59.341: ERROR/LZ(5963): receive Exception也就是说在receiveStream=socket.getInputStream();之前还显示socket状态正常,一用receiveStream=socket.getInputStream();就出错了我怀疑是不是因为sendStream.close();引起的问题,因为我看这一句的说明是:
Closes this stream. Implementations of this method should free any resources used by the stream. This implementation does nothing.should free any resources used by the stream
难道把socket的InputStream需要使用的资源也free了?
如果这样的话,我岂不是在sendStream.close();之后还得重新建个socket实例?在C#那边重新if(listener.Pending())一次?不是说TCP协议支持双工么?那这个Socket类跟单工有什么区别?完整代码如下:
Android客户端:int byteNum;
byte[] container=new byte[1024];
try{

socket = new Socket(serverIP,port);
sendStream = socket.getOutputStream();
String uploadStr=packUploadData("a05","p04","upload名字","upload信息",System.currentTimeMillis(),30666666,114666666,400,100);
convertStream= new ByteArrayInputStream(uploadStr.getBytes("GBK"));
while((byteNum=convertStream.read(container))!=-1){
sendStream.write(container, 0, byteNum);
Log.d(TAG, byteNum+" bytes wrote");
}
sendStream.flush();
sendStream.close();

}catch(Exception e){
Log.d(TAG, "send Exception");
}

Log.d(TAG, "ready to receive");
StringBuilder sb=new StringBuilder();
try{
Log.d(TAG,"socket.isClosed()="+socket.isClosed());
Log.d(TAG,"socket.isInputShutdown()="+socket.isInputShutdown());
receiveStream=socket.getInputStream();
while((byteNum=receiveStream.read(container))!=-1){
sb.append(new String(container,0,byteNum,"GBK"));
Log.d(TAG, byteNum+" bytes read");
}
Log.d(TAG,sb.toString()+"|测试结束符");
status_TV.setText(sb.toString());
receiveStream.close();
socket.close();
}catch(Exception e){

Log.e(TAG,e.getMessage());
Log.e(TAG, "receive Exception");
}C#服务器端:
if (listener.Pending())
                {
                    try
                    {
                        socket = listener.AcceptSocket();
                        byte[] container = new byte[1024];
                        receiveSBuilder = new StringBuilder();
                        while ((byteNum = socket.Receive(container)) != 0)
                        {
                            if (byteNum < container.Length)
                            {
                                receiveSBuilder.Append(System.Text.Encoding.Default.GetChars(container), 0, byteNum);
                            }
                            else
                            {
                                receiveSBuilder.Append(container);
                            }
                        }
                        string[] parts=spiltUserUpload(receiveSBuilder.ToString().TrimEnd('\0'));                        uploadSucceed = false;
                        if (parts[0] == "1")
                        {
                            uploadSucceed=proceedUserUpload(parts[1], parts[2], parts[3], parts[4], Convert.ToInt64(parts[5]), Convert.ToInt32(parts[6]), Convert.ToInt32(parts[7]), Convert.ToInt32(parts[8]), Convert.ToInt32(parts[9]));
                        }                        byte[] sendBytes;
                        if (uploadSucceed)
                        {
                             sendBytes= Encoding.Default.GetBytes("上传成功");
                        }
                        else {
                            sendBytes = Encoding.Default.GetBytes("错误,上传失败");
                        }                                               try
                        {
                            socket.Send(sendBytes, sendBytes.Length, 0);
                            socket.Close();
                            Console.WriteLine("bytes sent");
                        }
                        catch (Exception ee)
                        {
                            MessageBox.Show(ee.ToString());
                        }                            
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(e.Message);
                    }
                }

解决方案 »

  1.   

    不会吧   OutPutStream.close()什么都没做啊
    注意那一句"The close method of OutputStream does nothing."
      

  2.   


    但我这里确实出现问题了
    OutPutStream如果不close的话服务器端一直处于阻塞(Socket.Receive()一直在等),如果close OutPutStream的话,receiveStream=socket.getInputStream()又出异常刚才下午很无奈,只好在Android端重新开个线程,实例化一个ServerSocket,等待C#服务器端的连接我觉得这是件很蛋疼的事情哪位能够解决我1L的问题吗?谢谢了!