日期:2014-05-20  浏览次数:20646 次

java socket编程,如何告诉server流传输结束
我使用socket把一个xml文件发送到服务器,由服务器将数据流构造成xml文件后解析。
但是在客户端发完后,服务器因为无法判断已经传输完毕,所以一直停留在这句
String[] result=xml.extLogin(dis);
extLogin方法是我写的,进入后停留在构造xml Document对象上。
Document d=db.parse(is);

谁知道如何告诉服务器已经传输完毕,同时客户端又能接收服务器的响应数据????

代码如下
服务端的代码
Java code
DataInputStream dis =new DataInputStream(client.getInputStream());
                        String[] result=xml.extLogin(dis);
                        DataOutputStream dos = new DataOutputStream(client.getOutputStream());
                        
                        if(UserList.userList.containsKey(result[0])){
                            if(((String)UserList.userList.get(result[0])).equals(result[1])){
                                dos.writeUTF("SUCCESS");
                            }else{
                                dos.writeUTF("密码错误!");
                            }    
                        }else{
                            dos.writeUTF("用户名不存在!");
                        }


客户端代码:
Java code
DataInputStream data = new DataInputStream(new BufferedInputStream(new FileInputStream(file)));
            DataOutputStream toClient = new DataOutputStream(client.getOutputStream());
            DataInputStream fromServer=new DataInputStream(client.getInputStream());
            //toClient.writeUTF("login");
            //toClient.flush();
            /*
             * 传输文件
             * */
            int bufferSize = 1024;
            byte[] buf = new byte[bufferSize];
            while(true){
                int read=0;
                if(data!=null){
                    read=data.read(buf);
                }
                if(read==-1)
                    break;
                toClient.write(buf,0,read);
            }
            toClient.flush();
            
            /*
             * 如果使用下面注释掉的两句中的任何一句
             * server端能够收到结束符
             * 解析xml
             * 
             * 但是这里会抛出socket关闭异常
             * 同时服务器也报Socket is closed
             * 导致无法接收服务器返回的数据
             */
            //client.getOutputStream().close();
            //client.shutdownOutput();
            
            /*
             * 因为接收响应这段代码的存在
             * 不使用client.getOutputStream().close();
             * 或者client.shutdownOutput();
             * 导致服务器无法判断已经传输完毕
             * 卡在xml.extLogin(dis);这句上
             */
            String resp=fromServer.readUTF();


------解决方案--------------------
一般socket通讯的时候报文分报文头和报文体,报文头的长度是固定的,报文头标示报文体的长度和其他内容,按照这个规则,无论是client还是server都可以按指定长度接收了
------解决方案--------------------
文件流末尾增加判断常量字符:
Java code
  while(true){
                int read=0;
                if(data!=null){
                    read=data.read(buf);
                }
                if(read==-1){
                     byte[] buf2 = new byte[1025];
                    for(int i=0;i<1024;i++){
                    buf2[i]=buf[i];
                    buf2[i+1]=★;
                       }
                    break;
                 }
                toClient.write(buf,0,read);
            }
            toClient.flush();

------解决方案--------------------
还是按一楼的来吧,报头传递内容的长度,不然你服务器处理会出现问题的,一般都是按一个固定的字节数组来处理的,比如后面只有10个字节,但你还是按1024个去读会出现问题的。。。就会出现失真的情况了,有相应的SOCKETSERVER框架可以很容易的构建服务器基于报文的结构
------解决方案--------------------
这样吧:
Java code

while(true){
                int read=0;
                if(data!=null){
                    read=data.read(buf);
                }
                if(read==-1){
                     byte[] buf2 = new byte[10];
                    for(int i=0;i<10;i++){
                    
                    buf2[i]=★;
                   toClient.write(buf2,0,10);
                       }
                    break;
                 }
                toClient.write(buf,0,read);
            }
            toClient.flush();