问题描述
各位大神,我问个问题:我使用Socket写了一个服务器,别人访问我的时候,他程序启动之后,发送数据可以成功返回,然后再发送就失败,再次发送又成功了,以此循环下去,就是从第二次开始,每次发送,第一次是打开连接,第二次才是发送数据。publicclassEchoThreadextendsThread{protectedPrintStreamout;protectedStringmessage;protectedSocketclientSocket;publicEchoThread(SocketclientSocket){super();try{//接受数据,但不允许有中文,因为会乱码DataInputStreamin=newDataInputStream(clientSocket.getInputStream());byte[]buffer=newbyte[10000];//缓冲区的大小in.read(buffer);//处理接收到的报文,转换成字符串/***C++传递过来的中文字,需要转化一下。C++默认使用GBK。*GB2312是GBK的子集,只有简体中文。因为数据库用GB2312,所以这里直接转为GB2312**/message=newString(buffer,"GB2312").trim();this.clientSocket=clientSocket;//获得输出输出流out=newPrintStream(clientSocket.getOutputStream());}catch(IOExceptionex){Logger.getLogger(EchoServerThread.class.getName()).log(Level.SEVERE,null,ex);}finally{try{if(clientSocket!=null)clientSocket.close();}catch(IOExceptionex1){Logger.getLogger(EchoServerThread.class.getName()).log(Level.SEVERE,null,ex1);}}}publicvoidrun(){try{/***这里需要使用底层的byte方法来传递。因为即使直接写字符串,到底层还是调用了传递byte的方法。*这里涉及到编码问题。C++默认使用GBK,而GB2312是GBK的子集。*/byte[]responseBuffer=newClientRequestHandler(message).response().getBytes("GB2312");out.write(responseBuffer,0,responseBuffer.length);//Stringtest=newClientRequestHandler(message).response();//out.print(test);//直接UTF8输出,最终底层每个中文用3个字节传输//out.print(new//String(test.getBytes(),"GBK"));//转GBK失败,实际每个中文字用了4到5个字节传递//out.print(new//String(test.getBytes("GBK"),"GBK"));//转GBK,但底层还是要拆成字节数组,当然最终还是跟UTF8一样//sleep(1000);}catch(Exceptionex){Logger.getLogger(EchoThread.class.getName()).log(Level.SEVERE,null,ex);}try{clientSocket.close();}catch(IOExceptionex){Logger.getLogger(EchoThread.class.getName()).log(Level.SEVERE,null,ex);}}publicStringgetMessage(){returnmessage;}/***获取输出流**@return*/publicPrintStreamgetOutputStream(){returnout;}}
publicclassEchoServerThread{//服务端侦听的SocketServerSocketserverSkt=null;//构造方法publicEchoServerThread(intport){System.out.println("服务器代理正在监听,端口:"+port);try{//创建监听socketserverSkt=newServerSocket(port);}catch(IOExceptionex){Logger.getLogger(EchoServerThread.class.getName()).log(Level.SEVERE,null,ex);}while(true){try{//接收连接请求SocketclientSocket=serverSkt.accept();EchoThreadet=newEchoThread(clientSocket);//et.setDaemon(true);et.start();}catch(IOExceptione){System.out.println("无法接受当前客户连接请求!");break;}}}}
和这个问题是一模一样的:http://bbs.csdn.net/topics/330162464
解决方案
解决方案二:
你应该在服务端的处理线程中,通过while(true)去接收消息,你直接在线程的构造函数中接收了消息(实际上这时候还是在主线程运行的),并且立即将socket关闭了,所以你这里开启线程一点意义都没有。socket都关闭了,下次再发当然就不行了。至于你说的通一次断一次,依次循环,那应该是你的客户端对断了之后做了处理,就是接着下一次再重新连接。关键原因就是你的服务端收了一条消息之后就立即关闭了。
解决方案三:
楼上说的对,具体代码(示意代码)可能是这样:while(running){try{Socketsocket=socketServer.accept();BufferedReaderreader=newBufferedReader(newInputStreamReader(socket.getInputStream(),"UTF-8"));Stringcmd=reader.readLine();CmdCentercc=newCmdCenter(socket,reader,cmd);cc.setDaemon(false);cc.start();}catch(Exceptione){logger.error(e.getMessage());}}