Can you write to a sockets input and output stream at the same time?

前端 未结 3 1708
南方客
南方客 2021-01-04 08:58

I have a Java application which is Voip. I am using the one socket to send and receive information at the same time via threads. Code is shown below ..

Socke         


        
相关标签:
3条回答
  • 2021-01-04 09:36

    The reason it seems my write() is blocking is because I stupidly closed the Socket() and my input streams didn't realize it. Hence, no data is ever sent out. Silly error on my behalf.

    0 讨论(0)
  • 2021-01-04 09:38

    Yes you can write to a sockets input and output stream at the same time.

    from do-java-sockets-support-full-duplex

    Since the input stream and the output stream are separate objects within the Socket, the only thing you might concern yourself with is, what happens if you had 2 threads trying to read or write (two threads, same input/output stream) at the same time? The read/write methods of the InputStream/OutputStream classes are not synchronized. It is possible, however, that if you're using a sub-class of InputStream/OutputStream, that the reading/writing methods you're calling are synchronized. You can check the javadoc for whatever class/methods you're calling, and find that out pretty quick.

    0 讨论(0)
  • 2021-01-04 09:42

    Yes you can write on socket while reading , but you have to read socket in an independent thread. I am using this concept. Here the example is (read carefully it supports mutiple client as well ) :

    public class TeacherServerSocket {
    
    private Logger logger = Logger.getLogger(TeacherServerSocket.class);
    public static Map<String, TeacherServerThread> connectedTeacher = new HashMap<String, TeacherServerThread>();
    ServerSocket serverSocket;;
    
    @Override
    public void run() {
        // starting teacher server socket
        this.serverSocket = startServer();
        // if unable to to start then serverSocket would have null value
        if (null != this.serverSocket) {
    
            while (true) {
                 //listening to client for infinite time
                Socket socket = listenToClient();
                if (null != socket) {
    
                    TeacherServerThread teacherServerThread = new TeacherServerThread(socket);
                    Thread thread = new Thread(teacherServerThread);
                    thread.start();
    
                    //putting teacher ip address and teacher object into map
                    connectedTeacher.put(teacherServerThread.getTeacherIp(),teacherServerThread);
                    System.out.println("INFO: Teacher is connected with address "+ teacherServerThread.getTeacherIp());
    
                }
    
            }
    
    
        }
    
    }
    
    @Override
    public ServerSocket startServer() {
         //port number on which teacher server will  be run.
         int port=12345;
    
        try {
            // throw an exception if unable to bind at given port
            ServerSocket serverSocket = new ServerSocket(port);
            System.out.println("Teacher server socket started on port no :"+port);
            return serverSocket;
    
        } catch (IOException e) {
    
            logger.error("Unable to start Teacher Server socket");
            e.printStackTrace();
    
        }
    
        return null;
    
    }
    
    @Override
    
    public Socket listenToClient() {
    
        if (this.serverSocket != null) {
    
            try {
                // throw an exception is unable to open socket
                Socket socket = this.serverSocket.accept();
                return socket;
    
            } catch (IOException e) {
    
                logger.error("Unable to open socket for teacher");
                e.printStackTrace();
    
            }
        } 
        else {
    
            logger.error("TeacherServerSocket has got null value please restart the server");
    
        }
    
        return null;
    }
    
    
    
    
    
    @Override
    public Map getConnectedDevicesMap() {
    
    return  TeacherServerSocket.connectedTeacher;
    
    }
    
    /**
     * This method will send message to connected teacher which comes form  student
     * @author rajeev
     * @param   message, which comes form student
     * @return  void
     *   * */
    @Override
    public void publishMessageToClient(String message) {
        if(TeacherServerSocket.connectedTeacher.size()>0){
            System.out.println("Total Connected Teacher: "+TeacherServerSocket.connectedTeacher.size());
            for (String teacherIp : TeacherServerSocket.connectedTeacher.keySet()) {
    
                TeacherServerThread teacherServerThread=TeacherServerSocket.connectedTeacher.get(teacherIp);
                teacherServerThread.publishMessageToTeacher(message);
    
            }
        }
    
    }
    
    
    
    @Override
    public void stopServer() {
    
        if (this.serverSocket != null) {
    
            try {
    
                serverSocket.close();
    
            } catch (Exception e) {
    
                e.printStackTrace();
    
            }
        }
    
    }
    
    
    }
    

    To read in an in independent thread for multiple client :

    public class TeacherServerThread implements Runnable {
    
    
    Logger logger=Logger.getLogger(TeacherServerThread.class);
    Socket socket;
    String teacherIp;
    
    public TeacherServerThread(Socket socket) {
     this.socket=socket;
     this.teacherIp=socket.getInetAddress().toString();
    }
    
    
    @Override
    public void run() {
        //starting reading
        ReadFromTeacherAndPublishToStudent messageReader=new ReadFromTeacherAndPublishToStudent();
        Thread thread=new Thread(messageReader);
        thread.start();
    }
    
    
    
    
    
    private class ReadFromTeacherAndPublishToStudent implements Runnable {
    
        @Override
        public void run() {
            String message=null;
            try {
                BufferedReader readTeacherData=new BufferedReader(new InputStreamReader(socket.getInputStream()));
    
                StudentServerSocket studentServerSocket=new StudentServerSocket();
                //sending message to student which is read by teacher
                while((message=readTeacherData.readLine())!=null){
                    //System.out.println("Message found : "+message);
                   //  studentServerSocket.publishMessageToClient(message); // do more stuff here 
    
                }
                // if message has null value then it mean socket is disconnected.
          System.out.println("INFO: Teacher with IP address : "+teacherIp+" is disconnected");
          TeacherServerScoket.connectedTeacher.remove(getTeacherIp());
            if(null!=socket){
                socket.close();
            }
    
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    
    
    
    
    }
    
    } //class
    
    
    
    public void publishMessageToTeacher(String message){
    
        if(this.socket!=null){
    
            try {
    
            PrintWriter writeMessageToTeacher=new PrintWriter(this.socket.getOutputStream());
            writeMessageToTeacher.println(message);
            writeMessageToTeacher.flush();
            System.out.println(" Message published to teacher"+message);
            }catch(Exception e){
            logger.error(e.toString());
            logger.error("Exception In writing data to teacher");
    
            }
    
    
        }else {
            logger.error("Unable to publish message to teacher .Socket has Null value in publishMessageToTeacher");     
            System.out.println("ERROR: socket has null value can not publish to teacher");
        }
    
    
    
    }
    
    public String getTeacherIp()
    {
        return teacherIp;
    
    }
    }
    

    change code according to you requirement......

    0 讨论(0)
提交回复
热议问题