你能同时写入套接字输入和输出流吗?

我有一个Java应用程序,它是Voip。 我正在使用一个套接字通过线程同时发送和接收信息。 代码如下所示..

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

我发现的问题是,当我写入输出流时,它会在第一次写入时阻塞。 我发送的字节数不多。 贝娄是我的写代码。

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

我已经评论了很多实际代码,因为我只是想让它工作。 我的写函数在第一次写入时无限期地阻塞。 这可能是我的线程有问题吗? 我唯一的想法是输出和输入流共享我的套接字对象,这可能会导致死锁或其他东西。 请告诉我最新消息。

是的,您可以同时写入套接字输入和输出流。

来自do-java-sockets-support-full-duplex

由于输入流和输出流是Socket中的独立对象,因此您可能唯一关心的是,如果您有2个线程尝试读取或写入(两个线程,相同的输入/输出流),会发生什么?时间? InputStream / OutputStream类的读/写方法不同步。 但是,如果您使用的是InputStream / OutputStream的子类,则可能会同步您正在调用的读/写方法。 您可以检查javadoc以查找您正在调用的任何类/方法,并快速找到它。

是的,您可以在读取时写入套接字,但您必须在独立的线程中读取套接字。 我正在使用这个概念。 这里的例子是(仔细阅读它也支持多个客户端):

 public class TeacherServerSocket { private Logger logger = Logger.getLogger(TeacherServerSocket.class); public static Map connectedTeacher = new HashMap(); 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; } } 

根据你的要求改变代码……

我的write()似乎是阻塞的原因是因为我愚蠢地关闭了Socket()并且我的输入流没有意识到它。 因此,没有数据被发送出去。 代表我的愚蠢错误。