Do I need to sync socket.send?

I have 2 classes, where I have one to send commands to the socket, the other that receives (and sometimes responds to commands).

Does it need to sync? Or is it not necessary?

Both classes work in their threads with the socket object passed to each of them as an argument in thread.start();

Is this the right way to do this, or can I do something more efficient?

Would it be likely to cause errors? Sending part:

  public void run(){ send_chatline("roomf"); int vvv = 0; while (this.socket.isConnected()){ try{ Thread.sleep(10000); vvv++; Thread.sleep(10000); send_chatline("alive"); Thread.sleep(10000); if (vvv == 1) { this.socket.flush(); this.socket.send("T,-1," + this.playerid * 3); this.socket.flush(); } } catch (InterruptedException e) { e.printStackTrace(); } } } 

But remember! The recieveFromSock class also sometimes writes when certain commands appear.

The only function of sendTosock is to maintain a connection on the network (to be able to remain on the network).

+4
source share
4 answers

The only guarantee you have is that the byte sent is sent once, and the byte is read once. Others may say that synchronization is performed by the runtime library or the underlying operating system. Any such operator depends on execution and depends on the operating system and / or depends on the operating system (and, in my opinion, should be ignored).

So, if you have one stream reading from the socket and one stream writing to the socket, you should be fine without synchronization.

If more than one stream can be written to the socket, you should synchronize their actions to make sure that the output sent from the two streams does not alternate.

The same applies if two streams are read from a socket. You must synchronize the reads to ensure that the data read by one thread has no gaps due to the reading of another thread.

A similar question, the same conclusion:

+1
source

Does it need to sync?

Not. SocketImpl has its own internal synchronization. You won’t be surprised to know that the sending is not synchronized, but the receipt is.

+1
source

You do not need to synchronize, since synchronization is performed on the socket. The question arises: are two classes / streams transmitted through sockets living in the same JVM? If so, there are several more efficient options, the simplest of which is BlockingQueue , where the sender class adds its commands and the receiver accepts them.

+1
source

I was also curious for nio classes, and it is synchronized (only for nio). Just take a look at the write method here in the sun JVM code

http://www.docjar.com/html/api/sun/nio/ch/SocketChannelImpl.java.html

Checking the old code of the I / O socket, however, does not show synchronization, although there is a function to get FD and releaseFD ... but there is no sycnhronization ... which seems to prevent closing until all entries in all threads are completed (it looks like they assume that recording from multiple threads in each OS is good, but I don’t know if this is true, or they are synchronized in the JVM native code, so the developer knows that they can do this) .... we need JVM developer to tell us if there is a synchronization block in the JVM Windows, Linu x JVM and Mac JVM etc. etc. etc.

 private void socketWrite(byte b[], int off, int len) throws IOException { if (len <= 0 || off < 0 || off + len > b.length) { if (len == 0) { return; } throw new ArrayIndexOutOfBoundsException(); } FileDescriptor fd = impl.acquireFD(); try { socketWrite0(fd, b, off, len); } catch (SocketException se) { if (se instanceof sun.net.ConnectionResetException) { impl.setConnectionResetPending(); se = new SocketException("Connection reset"); } if (impl.isClosedOrPending()) { throw new SocketException("Socket closed"); } else { throw se; } } finally { impl.releaseFD(); } } 
0
source

Source: https://habr.com/ru/post/1403840/


All Articles