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

【小白求教】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条回答 默认 最新

      报告相同问题?

      相关推荐 更多相似问题

      悬赏问题

      • ¥15 如何修改为正确的?求解决
      • ¥15 django访问管理员界面问题
      • ¥20 python homework完成
      • ¥20 求解 多变量系统的最小二乘辨识问题的推导以及matlab仿真
      • ¥15 arduino esp8266 Blinker编译报问题
      • ¥15 ubuntu18.04运行模型,直接死机
      • ¥30 (问卷调查)莫名其妙丢了u盘,你们会是什么心理状态
      • ¥100 Spark+android应⽤案例
      • ¥15 yolov8 目标检测 重叠 遮挡
      • ¥20 微信聊天记录如何部署到服务器上