2013-01-24 42 views
7

मेरे पास जावा एप्लिकेशन है जो वीओआईपी है। मैं थ्रेड के माध्यम से एक ही समय में जानकारी भेजने और प्राप्त करने के लिए एक सॉकेट का उपयोग कर रहा हूं। कोड .. नीचे दिखाया गया हैक्या आप एक ही समय में एक सॉकेट इनपुट और आउटपुट स्ट्रीम लिख सकते हैं?

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

समस्या यह है कि मैं खोज रहा हूँ यह है कि जब मैं outputstream को लिखने, यह पहली लिखने पर ब्लॉक। मैं कई बाइट नहीं भेज रहा हूँ। भाई मेरा लेखन कोड है।

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){} 
    } 
} 

अन्य धागा है कि पढ़ता ध्वनि कोड है ...

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){} 
    } 

} 

मैं वास्तविक कोड का एक अच्छा भाग टिप्पणी की है के बाद से मैं सिर्फ यह काम करने के लिए प्राप्त करने की कोशिश कर रहा हूँ। मेरा लेखन कार्य पहले लिखने पर अनिश्चित काल तक ब्लॉक करता है। क्या यह संभव है कि यह मेरे धागे के साथ एक समस्या हो सकती है? मेरा एकमात्र विचार यह है कि आउटपुट और इनपुट स्ट्रीम मेरी सॉकेट ऑब्जेक्ट साझा कर रही हैं जो डेडलॉक या कुछ कारण बन सकती है। कृपया मुझे बताएं कि क्या हो रहा है।

उत्तर

11

हाँ आप एक ही समय में एक सॉकेट इनपुट और आउटपुट स्ट्रीम को लिख सकते हैं।

से do-java-sockets-support-full-duplex

के बाद से इनपुट स्ट्रीम और उत्पादन धारा सॉकेट के भीतर अलग वस्तुओं रहे हैं, केवल एक चीज आप अपने आप को चिंता का विषय हो सकता है के साथ, क्या यदि आप 2 धागे था पढ़ने या लिखने की कोशिश कर रहा होता है (दो धागे, एक ही इनपुट/आउटपुट स्ट्रीम) एक ही समय में? इनपुटस्ट्रीम/आउटपुटस्ट्रीम कक्षाओं के पढ़ने/लिखने के तरीके सिंक्रनाइज़ नहीं होते हैं। हालांकि, यह संभव है कि यदि आप इनपुटस्ट्रीम/आउटपुटस्ट्रीम के उप-वर्ग का उपयोग कर रहे हैं, तो आप जिस रीडिंग/लेखन विधियों को कॉल कर रहे हैं वे सिंक्रनाइज़ हैं। आप जो भी कक्षा/विधियों को बुला रहे हैं, उसके लिए जावाडोक देख सकते हैं, और इसे बहुत तेज़ी से ढूंढ सकते हैं।

+0

मैंने सोचा कि चूंकि अंदर और बाहर (दो अलग-अलग धाराएं) अलग-अलग वस्तुएं हैं, एक ही समय में उन पर परिचालन करना कोई फर्क नहीं पड़ता। तो आपकी कहानियां मुझे अभी भी सिंक्रनाइज़ेशन के बारे में चिंतित होना चाहिए, भले ही? –

4

हाँ आप पढ़ने के दौरान सॉकेट पर लिख सकते हैं, लेकिन आपको एक स्वतंत्र थ्रेड में सॉकेट पढ़ना होगा। मैं इस अवधारणा का उपयोग कर रहा हूँ। यहाँ उदाहरण है (यह रूप में अच्छी तरह एकाधिक ग्राहक का समर्थन करता है ध्यान से पढ़ें):

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

     } 
    } 

} 


} 

कई ग्राहक के लिए स्वतंत्र सूत्र में एक में पढ़ने के लिए: आप आवश्यकता के अनुसार

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; 

} 
} 

परिवर्तन कोड .... ..

+0

मैं पढ़ने और लिखने के लिए धागे का उपयोग कर रहा हूं। पढ़ने के लिए एक धागा और दूसरा लिखने के लिए। इसके अलावा मैं प्रिंटवाइटर का उपयोग नहीं कर सकता क्योंकि मुझे आदिम बाइट एरे भेजना है, यही मेरा ऑडियो डेटा है। –

0

ऐसा लगता है कि मेरा लेखन() अवरुद्ध है क्योंकि मैंने बेवकूफ रूप से सॉकेट() बंद कर दिया है और मेरी इनपुट धाराओं को इसका एहसास नहीं हुआ। इसलिए, कोई डेटा कभी नहीं भेजा जाता है। मेरी तरफ से मूर्खतापूर्ण त्रुटि।