zkzk7410 2017-04-26 14:12 采纳率: 68.8%
浏览 1821
已采纳

【小白求教】JAVA多线程跑ServerSocket内存逐渐爆满死机

第一个是教材上正确的代码,可以正常多线程运行的
主程序:
package com.server;
import java.io.*;
import java.util.*;
import java.net.*;
import com.bean.*;
import com.biz.ServerBiz;
public class MainServer {
private ServerSocket serverSocket;
private Socket socket;
private InputStream in;
private OutputStream out;

public MainServer() {
    //创建服务器的套接字
    try {
        serverSocket=new ServerSocket(8888);

        System.out.println("服务器已经启动.....");
        while(true){
            socket=serverSocket.accept();//监听并且接收客户端请求

            ServerBiz serverBiz=new ServerBiz(socket);

            Thread td=new Thread(serverBiz);//将serverBiz设置到线程中,每开一个客户端,会创建一个新的线程处理客户端的数据
            td.start();//开始
        }
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } 
}



/**
 * @param args
 */
public static void main(String[] args) {
    new MainServer();

}

}

package com.biz;
import java.io.*;
import java.util.*;
import java.net.*;
import com.bean.*;

public class ServerBiz implements Runnable {

private Socket socket;
private InputStream in;
private OutputStream out;

public ServerBiz(Socket socket) {
    this.socket=socket;
    try {
        in=socket.getInputStream();
        out=socket.getOutputStream();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}



@Override
public void run() {
    try {
        /************接收***************************************/
        in=socket.getInputStream();
        ObjectInputStream objin=new ObjectInputStream(in);
        Users us=(Users) objin.readObject();
        int code=0;//状态码
        if(us!=null){
            if(us.getUname()!=null&&!us.getUname().trim().equals("")
                    &&us.getPasswd()!=null&&!us.getPasswd().trim().equals("")){
                System.out.println("账号:"+us.getUname());
                System.out.println("密码:"+us.getPasswd());
                code=1;//登陆成功!
            }
        }
        socket.shutdownInput();//结束接收
        /******************************************************/

        /*****向客户端发送响应***************************************/
        out=socket.getOutputStream();
        out.write(code);//向客户端发送状态码
        out.flush();
        socket.shutdownOutput();//结束输出
        /******************************************************/
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }


}

}

以上是教材正确的代码,
我奇怪为什么不能将 socket=serverSocket.accept() 写在runnable中的run方法中,于是我修改成了下面的代码,可是这个是不能正常运行的。
先打开任务管理器,再运行这个程序,可以看到内存在很短的时间内逐渐爆满,从而导致电脑无法使用

主程序:
package com.server;

import java.net.*;
import java.io.*;

import com.bean.Users;
import com.biz.ServerBiz;

public class MainServer {
private ServerSocket ss;

public MainServer() {

        try {
            ss = new ServerSocket(8888);
            System.out.println("服务器已经启动......");
            /************************ 客户端发送来的消息 **************************/
            while (true) {

                ServerBiz sb=new ServerBiz(ss);
                Thread t=new Thread(sb);
                t.start();
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }


}

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

}

下面是设置的Runnable
package com.biz;
import java.net.*;
import java.io.*;

import com.bean.Users;

public class ServerBiz implements Runnable {
private ServerSocket ss;

public ServerBiz(ServerSocket ss) {

    this.ss = ss;
}


@Override
public void run() {
    try {
        Socket sk = ss.accept();
        InputStream ips = sk.getInputStream();
        ObjectInputStream objectin = new ObjectInputStream(ips);
        Users user = new Users();
        user = (Users) objectin.readObject();
        int code = 0;
        if (user != null && user.getPassword() != null
                && user.getUname() != null
                && !user.getPassword().trim().equals("")
                &&!user.getUname().trim().equals("")) {
            System.out.println("用户名:" + user.getUname());
            System.out.println("密码:" + user.getPassword());
            code = 1;
        }
        sk.shutdownInput();
        /**************************************************************/

        /************************ 向客户端发送的消息 **************************/
        OutputStream ops = sk.getOutputStream();
        ops.write(code);
        ops.flush();
        sk.shutdownOutput();
        /**************************************************************/
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}

}

(本来还有个client端,这里忽略)

求大神指点什么将 socket=serverSocket.accept() 写在Runnable中 ,运行后就死机啊,非常感谢啊!

  • 写回答

1条回答 默认 最新

  • ljheee 2017-04-26 14:33
    关注

    不能将 socket=serverSocket.accept() 写在runnable中的run方法中,
    serverSocket.accept() 是服务器接收到客户端连接,如果写在runnable中的run方法中,那意思就是——每一个子线程运行run方法时们都会serverSocket.accept()尝试去监听8888端口,

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 cplex运行后参数报错是为什么
  • ¥15 之前不小心删了pycharm的文件,后面重新安装之后软件打不开了
  • ¥15 vue3获取动态宽度,刷新后动态宽度值为0
  • ¥15 升腾威讯云桌面V2.0.0摄像头问题
  • ¥15 关于Python的会计设计
  • ¥15 聚类分析 设计k-均值算法分类器,对一组二维模式向量进行分类。
  • ¥15 stm32c8t6工程,使用hal库
  • ¥15 找能接spark如图片的,可议价
  • ¥15 关于#单片机#的问题,请各位专家解答!
  • ¥15 博通raid 的写入速度很高也很低