java.net.BindException: Address already in use: JVM_Bind

socket编程刚开始接触,做点小记录:

ps:在启动server后,重新运行时,会报错java.net.BindException: Address already in use: JVM_Bind

at java.net.DualStackPlainSocketImpl.bind0(Native Method)
at java.net.DualStackPlainSocketImpl.socketBind(DualStackPlainSocketImpl.java:106)
at java.net.AbstractPlainSocketImpl.bind(AbstractPlainSocketImpl.java:387)
at java.net.PlainSocketImpl.bind(PlainSocketImpl.java:190)
at java.net.ServerSocket.bind(ServerSocket.java:375)
at java.net.ServerSocket.<init>(ServerSocket.java:237)
at java.net.ServerSocket.<init>(ServerSocket.java:128)
at cn.com.xutengfei.server.SocketTest.<init>(SocketTest.java:35)

at cn.com.xutengfei.server.SocketTest.main(SocketTest.java:30)

相当于端口已被占用未关闭,再次运行服务时自然会报错,在这里就遇到过的问题做点小记录而已

demo:

服务器端(eclipse):

public class SocketServer {
    private static final int PORT = 1234;
    private List<Socket> mList = new ArrayList<Socket>();
    private ServerSocket server = null;
    private ExecutorService mExecutorService = null;
    private String receiveMsg;
    private String sendMsg;

    public static void main(String[] args) {
        new SocketTest();
    }

    public SocketServer () {
        try {
            server = new ServerSocket(PORT);
            mExecutorService = Executors.newCachedThreadPool();
            System.out.println("服务器已启动...");
            Socket client = null;
            while (true) {
                client = server.accept();
                mList.add(client);
                mExecutorService.execute(new Service(client));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    class Service implements Runnable {
        private Socket socket;
        private BufferedReader in = null;
        private PrintWriter printWriter = null;
        public Service(Socket socket) {
            this.socket = socket;
            try {
                printWriter = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), "UTF-8")), true);
                in = new BufferedReader(new InputStreamReader(
                        socket.getInputStream(), "UTF-8"));
                printWriter.println("成功连接服务器" + "(服务器发送)");
                System.out.println("成功连接服务器");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        public void run() {
            try {
                while (true) {
                    if ((receiveMsg = in.readLine()) != null) {
                        System.out.println("receiveMsg:" + receiveMsg);
                        if (receiveMsg.equals("0")) {
                            System.out.println("客户端请求断开连接");
                            printWriter.println("服务端断开连接" + "(服务器发送)");
                            mList.remove(socket);
                            in.close();
                            socket.close();
                            break;
                        } else {
                            sendMsg = "我已接收:" + receiveMsg + "(服务器发送)";
                            printWriter.println(sendMsg);
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

}

客户端:

// Socket变量
private Socket socket;
// 线程池
// 为了方便展示,此处直接采用线程池进行线程管理,而没有一个个开线程
private ExecutorService mThreadPool;
// 输入流对象
InputStream is;
// 输入流读取器对象
InputStreamReader isr;
BufferedReader br;
// 接收服务器发送过来的消息
String response;
// 输出流对象
OutputStream outputStream;
// 初始化线程池
mThreadPool = Executors.newCachedThreadPool();

@Override
public void onClick(View view) {
    switch (view.getId()) {
        case R.id.btn_connect:
            // 利用线程池直接开启一个线程 & 执行该线程
            mThreadPool.execute(new Runnable() {
                @Override
                public void run() {

                    try {
                        // 创建Socket对象 & 指定服务端的IP 及 端口号
                        socket = new Socket(IP, 1234);
                        // 判断客户端和服务器是否连接成功
                        System.out.println(socket.isConnected());

                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                }
            });
            break;
        case R.id.btn_send:
            // 利用线程池直接开启一个线程 & 执行该线程
            mThreadPool.execute(new Runnable() {
                @Override
                public void run() {

                    try {
                        // 步骤1:从Socket 获得输出流对象OutputStream
                        // 该对象作用:发送数据
                        outputStream = socket.getOutputStream();

                        // 步骤2:写入需要发送的数据到输出流对象中
                        outputStream.write(("1" + "\n").getBytes("utf-8"));
                        // 特别注意:数据的结尾加上换行符才可让服务器端的readline()停止阻塞

                        // 步骤3:发送数据到服务端
                        outputStream.flush();

                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                }
            });
            break;
        case R.id.btn_receive:
            // 利用线程池直接开启一个线程 & 执行该线程
            mThreadPool.execute(new Runnable() {
                @Override
                public void run() {

                    try {
                        // 步骤1:创建输入流对象InputStream
                        is = socket.getInputStream();

                        // 步骤2:创建输入流读取器对象 并传入输入流对象
                        // 该对象作用:获取服务器返回的数据
                        isr = new InputStreamReader(is);
                        br = new BufferedReader(isr);

                        // 步骤3:通过输入流读取器对象 接收服务器发送过来的数据
                        response = br.readLine();

                        // 步骤4:通知主线程,将接收的消息显示到界面
                        Message msg = Message.obtain();
                        msg.what = 0;
                        mMainHandler.sendMessage(msg);

                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                }
            });
            break;
        case R.id.btn_close:
                // 利用线程池直接开启一个线程 & 执行该线程
                mThreadPool.execute(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            //通知服务器断开连接
                            outputStream = socket.getOutputStream();
                            outputStream.write(("0" + "\n").getBytes("utf-8"));
                            outputStream.flush();

                        } catch (IOException e) {
                            e.printStackTrace();
                        }

                    }
                });
            break;
    }
}
在测试过程中,客户端主动断开连接后,再次连接服务端,发送数据时,服务端无法接收到数据1;发送断开连接请求,通知服务端来断开连接时,再次连接服务端,发送数据时,服务端正常接收到数据1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值