java: Single socket on read write operation. Full

2019-08-06 13:52发布

问题:

I have to implement sending data with specific source port and in the same time listen to that port. Full duplex. Does anybody know how to implement it on java. I tried to create separate thread for listening on socket input stream but it doesnt work. I cannot bind ServerSocket and client socket to the same source port and the the same with netty. It there any solution for dull duplex?

    init(){
    socket = new Socket(InetAddress.getByName(Target.getHost()), Target.getPort(), InetAddress.getByName("localhost"), 250);
    in = new DataInputStream(socket.getInputStream());
    out = new DataOutputStream(socket.getOutputStream());
    }

     private static void writeAndFlush(OutputStream out, byte[] b) throws IOException {
        out.write(b);
        out.flush();
      }


    public class MessageReader implements Runnable {

        @Override
        public void run() {
//this method throw exception EOF
          read(in);

          }
private void read(DataInputStream in){
 while (isConnectionAlive()) {
          StringBuffer strBuf = new StringBuffer();
          byte[] b = new byte[1000];
          while ((b[0] = bufferedInputStream.read(b)) != 3) {
            strBuf.append(new String(b));
          }
          log.debug(strBuf.toString());
        }
}
        }

回答1:

I had run into the same question and decided to answer it myself. I would like to share with you guys the code repo. It is really simple, you can get the idea to make your stuff work. It is an elaborate example. The steps accidentally look like Ordous's solution.

https://github.com/khanhhua/full-duplex-chat

Feel free to clone! It's my weekend homework.



回答2:

Main thread:

  • Create background thread(s) that will connect to any target machines(s).
    • These threads will connect to target machines and transmit data and die
  • Create an infinite loop
    • Listen for incoming connections.
      • Thread off any connection to handle I/O

Classes:

  • Server
    • Listens for incoming connections and threads off a Client object
  • Client
    • This class is created upon the server accepting the incoming connection, the TcpClient or NetClient (i forget what java calls it) is used to send data. Upon completion it dies.
  • Target
    • Is created during the start up and connects to a specific target and send data.
    • once complete it dies.


回答3:

What you're trying to do is quite strange: A ServerSocket is a fully implemented socket that accepts connections, it handles its own messages and you definitely cannot piggy-back another socket on top of it.

Full duplex is fairly simple to do with NIO:

  1. Create a Channel for your Socket in non-blocking mode
  2. Add read to the interest OPs
  3. Sleep with a Selector's select() method
  4. Read any readable bytes, write any writable bytes
  5. If writing is done, remove write from interest OPs
  6. GOTO 3.
  7. If you need to write, add bytes to a buffer, add write to interest OPs and wake up selector. (slightly simplified, but I'm sure you can find your way around the Javadoc)

This way you will be completely loading the outgoing buffer every time there is space and reading from the incoming one at the same time (well, single thread, but you don't have to finish writing to start reading etc).