如何在Java服务器上接受多个套接字连接

时间:2014-04-06 18:03:22

标签: java android sockets

我正在尝试使用标准Java套接字在Android中实现客户端 - 服务器对。到目前为止,我已经成功实现了一对一的客户端 - 服务器连接。现在,我正在修改我的服务器端代码以接受多个客户端连接。我从here获得了帮助。我正在创建一个serverSocket并在无限循环中等待客户端连接。一旦客户端socked被接受,我运行一个新的线程来处理该客户端,然后再次等待新的连接。不幸的是,该程序因某种未知原因而不断崩溃! logcat只是说 - “错误打开跟踪文件:没有这样的文件或目录”。文件路径是正确的(它在较旧的实现中工作正常)。任何人都可以建议我做错了什么?它与缺少清单权限有关吗?这是我到目前为止所做的:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Intent launchFileManager = new Intent(getBaseContext(),
            FileChooserActivity.class);
    startActivityForResult(launchFileManager, REQUEST_CODE); //receives files
    //fileArray has been populated here

    Button btn=(Button)findViewById(R.id.dispFilesid);
    btn.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            initializeServer();
        }
    });
}

private void initializeServer() {
    boolean listening = true;
    try {
        serversocket = new ServerSocket(4444);
    } catch (IOException e) {
        e.printStackTrace();
        Log.d("Listen failed", "Listening to port 4444 failed");
    }
    while (listening) {
        try {
            socket = serversocket.accept();
            Thread Clienttrd = new Thread(new Runnable() {
                @Override
                public void run() {

                    try {
                        OutputStream myos=socket.getOutputStream();
                        myos.write(filepathNameArray.size()); //send file count
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }

                    if (!fileArray.isEmpty()) {
                        for (int i = 0; i < filepathNameArray.size(); i++){
                            copyFile(fileArray.get(i), fileArray.get(i).getName().toString());
                            //mtv.setText(fileArray.get(i).getName().toString());
                        }
                    }
                }
            });
            Clienttrd.start();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

FileChooserActivity的意图返回包含文件URI列表的ArrayList。然后将这些URI包装在文件中并通过Socket对象的DataOutputStream写入。 请帮忙。任何见解将不胜感激!提前谢谢!

1 个答案:

答案 0 :(得分:1)

终于解决了这个问题。这可能有助于将来登陆此页面的其他人。问题:我使用相同的线程来接受和处理客户端连接。因此,服务器无法自由监听其他传入连接。我写了一个单独的ConnectionHandler类来处理客户端连接:

btn.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {

            Thread trd = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        serversocket = new ServerSocket(4444);
                    } catch (IOException e) {
                        e.printStackTrace();
                        Log.d("Listen failed",
                                "Listening to port 4444 failed");
                    }

                    while (listening) {
                        try {
                            socket = serversocket.accept();
                            Runnable connectionHandler = new ConnectionHandler(
                                    socket, fileArray, filepathNameArray);
                            new Thread(connectionHandler).start();
                        } catch (IOException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                }
            });
            trd.start();
        }
    });

ConnectionHandler(这解决了我的问题):

    public class ConnectionHandler implements Runnable {

    private Socket socket=null;
    private ArrayList<File> fileArray=null;
    ArrayList<String> filepathNameArray=null;

    public ConnectionHandler(Socket socket, ArrayList<File> fileArray, ArrayList<String> filepathNameArray) {
        super();
        this.socket = socket;
        this.fileArray=fileArray;
        this.filepathNameArray=filepathNameArray;
    }
    @Override
    public void run() {
        try {
            OutputStream myos=socket.getOutputStream();
            myos.write(filepathNameArray.size()); //send file count
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        if (!fileArray.isEmpty()) {
            for (int i = 0; i < filepathNameArray.size(); i++){
                copyFile(fileArray.get(i), fileArray.get(i).getName().toString());
                //mtv.setText(fileArray.get(i).getName().toString());
            }
        }

    }
    private void copyFile(File file, String name) {
        FileInputStream fis;
        long filesize = file.length();
        try {
            fis = new FileInputStream(file);
            BufferedInputStream bis = new BufferedInputStream(fis);
            @SuppressWarnings("resource")
            DataInputStream dis = new DataInputStream(bis);
            byte[] mybytearray = new byte[16384];
            OutputStream os;
            if (socket != null) {
                os = socket.getOutputStream();
                DataOutputStream dos = new DataOutputStream(os);
                dos.writeUTF(name); // filename is also sent to client
                dos.writeLong(filesize); // file size is also sent to client
                long z = filesize;
                int n = 0;
                while ((z > 0)
                        && (n = dis.read(mybytearray, 0,
                                (int) Math.min(mybytearray.length, z))) != -1) {
                    dos.write(mybytearray, 0, n);
                    dos.flush();
                    z -= n;
                }
            }
        } catch (FileNotFoundException e1) {
            e1.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}