[求助] socket通信.客户端怎样主动断开连接.

爱吃窝窝头 2014-11-07 10:21:30
如题,客户端怎样主动强制和服务器断开, 调用socket.close()后服务器inputstream.read()无限循环得到空字符串

服务器部分代码:
private void socket(){
ServerSocket ss;
try {
ss = new ServerSocket(9988);
//等待连接 客户端
System.out.println("正在侦听");
Socket s=ss.accept();
System.out.println("-----------连接成功-----------");
InputStream in=s.getInputStream();

out= s.getOutputStream();

//读取从客户端法发来的信息
while(true) {
//读取从客户端发来的信息
byte[] b=new byte[1024];

in.read(b);

String info=new String(b).trim();
//在文本栏里显示
area_showWindow.append("客户端:"+info+"\r\n");
}
} catch (IOException e) {
e.printStackTrace();
}
}


客户端部分代码:
private void btn_send(){
btn_send.addActionListener(new ActionListener() {

@Override
public void actionPerformed(ActionEvent e) {
String info = area_inputWindow.getText();
if(info.equals("1")){
try {
out.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
area_showWindow.append("客户端: "+info+"\r\n");
try {
out.write(info.getBytes());
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
area_inputWindow.setText("");
}
});
}


客户端文本域就一直不停的增加:
客户端:
客户端:
客户端:
客户端:
客户端:
........N多
...全文
1126 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
冥王之锤 2014-11-13
  • 打赏
  • 举报
回复
server端问题,没有对未读取的情况进行判断,jdk中代码如下:
     * @return     the total number of bytes read into the buffer, or
     *             <code>-1</code> if there is no more data because the end of
     *             the stream has been reached.
     * @exception  IOException  If the first byte cannot be read for any reason
     * other than the end of the file, if the input stream has been closed, or
     * if some other I/O error occurs.
     * @exception  NullPointerException  if <code>b</code> is <code>null</code>.
     * @see        java.io.InputStream#read(byte[], int, int)
     */
    public int read(byte b[]) throws IOException {
        return read(b, 0, b.length);
    }
if there is no more data because the end of stream has been reached return -1. 未读取返回-1判断下。
  • 打赏
  • 举报
回复
你客户端while(true)这个循环不能结束。
humanity 2014-11-13
  • 打赏
  • 举报
回复
正常的读取都需要检测 read 方法的返回值是否 -1,-1 就表示没有东西了,停下来就好了。 如果你想明确的告诉对方你要断开连接的话,就直接 socket.getInputStream().close() 就好了, input stream 在 close 之后就会发出通知对方知道你断开连接了。 我虽然不知道具体 TCP 怎么工作的,只是了解建立连接有几个握手的步骤,断开连接也一样,只要步骤正确对方就知道我们想断开连接。不按步骤来的话,对方会得到 connection reset 这个 IOException,而且操作系统显示这个 socket 端口的状态也持续一段时间的 close waiting。
xiaomm627 2014-11-11
  • 打赏
  • 举报
回复
服务器端加异常处理, 就拿readLine来说: cmdjson = br.readLine();//当客户端保持连接时,这里会产生阻塞,后面代码不会执行。 直到客户端有数据发送过过来。 if(cmdjson != null) { //注意 但若客户端关闭连接,则readLine不会阻塞,会一直获取为null,因此值为null的时候要退出线程,否则就是个死循环消耗大量cpu //正常逻辑 }else{ //若执行到此,说明客户端已断开连接。你再做处理 }
捏造的信仰 2014-11-10
  • 打赏
  • 举报
回复
楼主你没有判断 read() 方法的返回值,这样是不对的。下面是一个简单的例子:
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class SocketBasic {

    public static final int PORT = 23123;

    public static final int BUFFER_SIZE = 4096;

    public static void main(String[] args) throws Exception {
        new Server().start();
        new Client().start();
    }

    ////////////////////////////////////////////////////////////////

    /**
     * 服务器端
     */
    static class Server {

        public void start() throws Exception {
            
            // 服务器端使用单独的侦听线程,该线程不会停止,所以程序需要手动停止
            Runnable runnable = new Runnable() {

                public void run() {
                    try {
                        ServerSocket serverSocket = new ServerSocket(PORT);

                        while (true) {
                            // 接受客户端连接,并且将连接得到的 Socket 对象交给会话线程处理
                            Socket accept = serverSocket.accept();
                            new Thread(new ServerSession(accept)).start();
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            };

            new Thread(runnable).start();
        }
    }

    /**
     * 会话线程
     */
    static class ServerSession implements Runnable {

        private Socket socket;

        ServerSession(Socket socket) {
            this.socket = socket;
        }

        @Override
        public void run() {
            try {
                run0();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        private void run0() throws Exception {
            InputStream $i = this.socket.getInputStream();
            byte[] buffer = new byte[BUFFER_SIZE];
            int readCount;

            // read() 方法返回 -1 表示客户端关闭了连接
            while ((readCount = $i.read(buffer)) != -1) {
                System.out.println("收到消息: " + new String(buffer, 0, readCount));
            }

            System.out.println("客户端关闭了连接,会话结束。");
        }
    }

    /**
     * 客户端
     */
    static class Client {

        public void start() throws Exception {
            for (int i = 0; i < 3; i++) {
                Socket socket = new Socket("127.0.0.1", PORT);
                String msg = "Hello, now is " + System.currentTimeMillis();
                socket.getOutputStream().write(msg.getBytes());
                socket.close();

                Thread.sleep(1000);
            }
        }
    }
}
泣血龙 2014-11-07
  • 打赏
  • 举报
回复
个人建议将对用户的处理过程封到线程里边去。。。然后不论线程如何奔溃你的主线程还是安全的,可以继续接受信号,不会崩掉。
泣血龙 2014-11-07
  • 打赏
  • 举报
回复
在调用close前发送个关闭信号,让服务器那边直接关了,这个可以不,我没试过这是我的个人想法。
俺是小王子 2014-11-07
  • 打赏
  • 举报
回复
shutdown 查一下接口有没有这样的方法

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧