2013-01-24 39 views
7

Tôi có một ứng dụng Java là Voip. Tôi đang sử dụng một socket để gửi và nhận thông tin cùng một lúc thông qua các luồng. Mã được hiển thị bên dưới ..Bạn có thể ghi vào luồng đầu vào và đầu ra của ổ cắm cùng một lúc không?

Socket clientSocket = sockList.accept(); 
OutputStream outSock = clientSocket.getOutputStream(); 
InputStream inSock = clientSocket.getInputStream(); 
new Thread(new Capture(outSock)).start(); 
new Thread(new PlayAudio(inSock)).start(); 
outSock.close(); 
clientSocket.close(); 

Vấn đề mà tôi tìm thấy là khi tôi viết vào dòng đầu ra, nó chặn trên chữ viết đầu tiên. Tôi đang gửi không nhiều byte. Dưới đây là viết mã của tôi.

private class Capture implements Runnable{ 

    private OutputStream out; 
    public Capture(OutputStream out){ 
     this.out = out; 
    } 
    @Override 
    public void run() { 
     try{ 
      int numBytesRead; 
      TargetDataLine outLine = getMic(); 
      outLine.open(); 
      outLine.start(); 

      byte[] data = new byte[outLine.getBufferSize()/5]; 
      byte[] test = {0x1,0x1,0x1}; 

      while(true) {  
       //numBytesRead = outLine.read(data, 0, data.length); 
       //System.out.println(numBytesRead); 
       out.write(test, 0, test.length); 
       out.flush(); 
       /*if(numBytesRead > 0){ 
        out.write(data, 0, data.length); 
        System.out.println("C"); 
       }*/ 
      } 
     }catch(Exception ex){} 
    } 
} 

Các chủ đề khác mà đọc mã âm thanh ...

private class PlayAudio implements Runnable{ 

    private InputStream in; 
    public PlayAudio(InputStream in){ 
     this.in = in; 
    } 
    @Override 
    public void run() { 
     int write; 
     try{ 
     SourceDataLine inLine = getSpeaker(); 
     inLine.open(); 
     inLine.start(); 
     byte[] data = new byte[inLine.getBufferSize()]; 
     byte[] test = new byte[3]; 
     while(true){ 
      System.out.println(1); 
      //write = in.read(data, 0, data.length); 
      in.read(test, 0 , test.length); 
      System.out.println(2); 
      /*if(write > 0){ 
       inLine.write(data, 0, write); 
       System.out.println(3); 
       System.out.println(write); 
      }*/ 
     } 
     } catch(Exception ex){} 
    } 

} 

tôi đã nhận xét một phần tốt đẹp của mã thực tế kể từ khi tôi chỉ cố gắng để có được nó để làm việc. Chức năng viết của tôi chặn vô thời hạn vào lần viết đầu tiên. Có thể điều này có thể là một vấn đề với chủ đề của tôi? Suy nghĩ duy nhất của tôi là các luồng đầu vào và đầu vào đang chia sẻ đối tượng socket của tôi có thể gây ra bế tắc hoặc cái gì đó. Xin vui lòng cho tôi biết whats up.

Trả lời

11

Có, bạn có thể ghi vào luồng đầu vào và đầu ra của ổ cắm cùng một lúc.

từ do-java-sockets-support-full-duplex

Kể từ khi dòng đầu vào và dòng đầu ra là các đối tượng riêng biệt trong Socket, điều duy nhất bạn có thể quan tâm mình với, những gì sẽ xảy ra nếu bạn đã có 2 đề cố gắng để đọc hoặc viết (hai luồng, cùng một luồng đầu vào/đầu ra) cùng một lúc? Các phương thức đọc/ghi của các lớp InputStream/OutputStream không được đồng bộ hóa. Tuy nhiên, có thể, nếu bạn đang sử dụng một lớp con của InputStream/OutputStream, thì các phương thức đọc/ghi mà bạn đang gọi được đồng bộ hóa. Bạn có thể kiểm tra javadoc cho bất kỳ lớp/phương pháp nào bạn đang gọi và tìm ra điều đó khá nhanh.

+0

Tôi nghĩ rằng từ trong ra ngoài (hai dòng riêng biệt) là các đối tượng riêng biệt, hoạt động trên chúng cùng một lúc không quan trọng. Vì vậy, nói của bạn tôi vẫn nên lo lắng về đồng bộ hóa, bất kể? –

4

Có bạn có thể viết trên ổ cắm trong khi đọc, nhưng bạn phải đọc ổ cắm trong một sợi độc lập. Tôi đang sử dụng khái niệm này. Dưới đây là ví dụ (đọc kỹ nó hỗ trợ mutiple khách hàng cũng):

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(); 

     } 
    } 

} 


} 

Để đọc trong một trong thread độc lập cho nhiều khách hàng:

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; 

} 
} 

đang thay đổi theo yêu cầu bạn .... ..

+0

Tôi đang sử dụng các chủ đề để đọc và viết. Một chủ đề để đọc và một để viết. Ngoài ra tôi không thể sử dụng PrintWriter vì tôi phải gửi các mảng byte nguyên thủy, đây là dữ liệu âm thanh của tôi. –

0

Lý do có vẻ như chữ viết() của tôi bị chặn là vì tôi đã đóng Ngầm Socket() và luồng đầu vào của tôi không nhận ra nó. Do đó, không có dữ liệu nào được gửi đi. Lỗi ngớ ngẩn thay mặt tôi.

Các vấn đề liên quan