tanszek:oktatas:iss_t:java_example_for_blocking_and_non-blocking_socket
Differences
This shows you the differences between two versions of the page.
Next revision | Previous revision | ||
tanszek:oktatas:iss_t:java_example_for_blocking_and_non-blocking_socket [2023/03/05 16:35] – létrehozva knehez | tanszek:oktatas:iss_t:java_example_for_blocking_and_non-blocking_socket [2024/03/04 08:00] (current) – [Blocking UDP sockets in Java] knehez | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | ==== Blocking TCP based sockets in Java ==== | + | ==== Blocking TCP sockets in Java ==== |
- | === Socket server source code === | + | === Blocking |
- | <code java> | + | <sxh java> |
+ | package org.ait; | ||
import java.io.IOException; | import java.io.IOException; | ||
import java.io.ObjectInputStream; | import java.io.ObjectInputStream; | ||
Line 22: | Line 23: | ||
try { | try { | ||
// 1. create a socket server listening to port 8080 | // 1. create a socket server listening to port 8080 | ||
- | providerSocket = new ServerSocket(8080, 10); | + | providerSocket = new ServerSocket(8080); |
// 2. waiting for the connection (here we are waiting until next connection) | // 2. waiting for the connection (here we are waiting until next connection) | ||
connection = providerSocket.accept(); | connection = providerSocket.accept(); | ||
Line 71: | Line 72: | ||
} | } | ||
} | } | ||
- | </code> | + | </sxh> |
- | === Socket client source === | + | === Blocking |
- | <code java> | + | <sxh java> |
+ | package org.ait; | ||
import java.io.IOException; | import java.io.IOException; | ||
import java.io.ObjectInputStream; | import java.io.ObjectInputStream; | ||
Line 137: | Line 139: | ||
} | } | ||
} | } | ||
- | </code> | + | </sxh> |
- | ==== Non-blocking TCP based sockets in Java ==== | + | ==== Blocking UDP sockets in Java ==== |
The following Agent sends a message and waits for a response on port 8080, also with UDP. Older versions of the Eclipse IDE, the text you type on the console can be sent by pressing ctrl+z | The following Agent sends a message and waits for a response on port 8080, also with UDP. Older versions of the Eclipse IDE, the text you type on the console can be sent by pressing ctrl+z | ||
- | <code java> | + | <sxh java> |
- | package org.ait; | + | package org.ait; |
+ | |||
+ | import java.io.BufferedReader; | ||
+ | import java.io.InputStreamReader; | ||
+ | import java.net.DatagramPacket; | ||
+ | import java.net.DatagramSocket; | ||
+ | import java.net.InetAddress; | ||
+ | |||
+ | public class UDPClient { | ||
+ | public static void main(String args[]) throws Exception { | ||
+ | BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in)); | ||
+ | DatagramSocket clientSocket = new DatagramSocket(); | ||
+ | InetAddress IPAddress = InetAddress.getByName(" | ||
+ | |||
+ | byte[] sendData = new byte[1024]; | ||
+ | byte[] receiveData = new byte[1024]; | ||
+ | |||
+ | String sentence = inFromUser.readLine(); | ||
+ | sendData = sentence.getBytes(); | ||
+ | |||
+ | DatagramPacket sendPacket = new DatagramPacket(sendData, | ||
+ | clientSocket.send(sendPacket); | ||
+ | |||
+ | DatagramPacket receivePacket = new DatagramPacket(receiveData, | ||
+ | clientSocket.receive(receivePacket); | ||
+ | String modifiedSentence = new String(receivePacket.getData()); | ||
+ | |||
+ | System.out.println(" | ||
+ | clientSocket.close(); | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | The UDP server waits for the agents messages on port 8080 and converts them to uppercase letters and sends them back to the client UDP socket. | ||
+ | |||
+ | <sxh java> | ||
+ | package org.ait; | ||
+ | |||
+ | import java.net.DatagramPacket; | ||
+ | import java.net.DatagramSocket; | ||
+ | import java.net.InetAddress; | ||
+ | |||
+ | public class UDPServer { | ||
+ | public static void main(String args[]) throws Exception { | ||
+ | |||
+ | DatagramSocket serverSocket = new DatagramSocket(8080); | ||
+ | |||
+ | byte[] bytesReceived = new byte[1024]; | ||
+ | byte[] bytesSent = new byte[1024]; | ||
+ | |||
+ | DatagramPacket receivePacket = new DatagramPacket(bytesReceived, | ||
+ | // here we are waiting for the packets | ||
+ | serverSocket.receive(receivePacket); | ||
+ | |||
+ | String textMessage = new String(receivePacket.getData()); | ||
+ | |||
+ | System.out.println(" | ||
+ | |||
+ | InetAddress IPAddress = receivePacket.getAddress(); | ||
+ | int port = receivePacket.getPort(); | ||
+ | |||
+ | String upperCaseText = textMessage.toUpperCase(); | ||
+ | bytesSent = upperCaseText.getBytes(); | ||
+ | |||
+ | // send back | ||
+ | DatagramPacket sendPacket = new DatagramPacket(bytesSent, | ||
+ | serverSocket.send(sendPacket); | ||
+ | serverSocket.close(); | ||
+ | |||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ==== Non-blocking TCP sockets in Java ==== | ||
+ | {{: | ||
+ | |||
+ | Reading: | ||
+ | |||
+ | * http:// | ||
+ | * http:// | ||
+ | |||
+ | |||
+ | {{tanszek: | ||
+ | |||
+ | |||
+ | ===== Non-blocking loop ===== | ||
+ | <sxh java> | ||
+ | | ||
+ | |||
+ | | ||
+ | | ||
+ | |||
+ | | ||
+ | SocketChannel socketChannel = serverSocketChannel.accept(); | ||
+ | |||
+ | if(socketChannel != null){ | ||
+ | // the connection is accepted | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | |||
+ | ===== Non-blocking Java client example ===== | ||
+ | |||
+ | <sxh java> | ||
+ | import java.io.IOException; | ||
+ | import java.io.InputStream; | ||
+ | import java.io.OutputStream; | ||
+ | import java.net.Socket; | ||
+ | import java.util.Random; | ||
| | ||
- | | + | |
- | import java.io.InputStreamReader; | + | private String host; |
- | import java.net.DatagramPacket; | + | private int port; |
- | | + | |
- | | + | |
| | ||
- | public class UDPClient { | + | // Bounds on how much we write per cycle |
- | public | + | private |
- | BufferedReader inFromUser | + | private static final int maxWriteSize = 65536; |
- | DatagramSocket clientSocket | + | |
- | InetAddress IPAddress = InetAddress.getByName(" | + | // Bounds on how long we wait between cycles |
- | + | private static final int minPause | |
- | byte[] sendData = new byte[1024]; | + | private static final int maxPause |
- | byte[] receiveData | + | |
- | + | // Random number generator | |
- | String sentence = inFromUser.readLine(); | + | Random rand = new Random(); |
- | sendData = sentence.getBytes(); | + | |
- | + | public Client(String host, int port, int numThreads) { | |
- | DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, 8080); | + | this.host = host; |
- | clientSocket.send(sendPacket); | + | this.port |
- | + | | |
- | DatagramPacket receivePacket | + | for (int i = 0; i < numThreads; ++i) { |
- | clientSocket.receive(receivePacket); | + | new Thread(this).start(); |
- | String modifiedSentence = new String(receivePacket.getData()); | + | } |
- | + | ||
- | System.out.println(" | + | |
- | clientSocket.close(); | + | |
} | } | ||
+ | | ||
+ | public void run() { | ||
+ | byte buffer[] = new byte[maxWriteSize]; | ||
+ | try { | ||
+ | Socket s = new Socket(host, | ||
+ | InputStream in = s.getInputStream(); | ||
+ | OutputStream out = s.getOutputStream(); | ||
+ | | ||
+ | while (true) { | ||
+ | int numToWrite = minWriteSize | ||
+ | + (int) (rand.nextDouble() * (maxWriteSize - minWriteSize)); | ||
+ | for (int i = 0; i < numToWrite; ++i) { | ||
+ | buffer[i] = (byte) rand.nextInt(256); | ||
+ | } | ||
+ | out.write(buffer, | ||
+ | int sofar = 0; | ||
+ | while (sofar < numToWrite) { | ||
+ | sofar += in.read(buffer, | ||
+ | } | ||
+ | System.out.println(Thread.currentThread() + " wrote " + numToWrite); | ||
+ | | ||
+ | int pause = minPause + (int) (rand.nextDouble() * (maxPause - minPause)); | ||
+ | try { | ||
+ | Thread.sleep(pause); | ||
+ | } catch (InterruptedException ie) { | ||
+ | } | ||
+ | } | ||
+ | } catch (IOException ie) { | ||
+ | ie.printStackTrace(); | ||
+ | } | ||
} | } | ||
- | </ | + | |
+ | static public void main(String args[]) throws Exception { | ||
+ | new Client(" | ||
+ | } | ||
+ | } | ||
- | The UDP server waits for the agents messages on port 8080 and converts them to uppercase letters and sends them back to the client UDP socket. | + | </ |
- | <code java> | + | |
- | | + | ===== Non-blocking Java server example ===== |
- | + | <sxh java> | |
- | | + | |
- | | + | // The port we will listen on |
- | | + | private int port; |
- | + | // A pre-allocated buffer for encrypting data | |
- | | + | private final ByteBuffer buffer = ByteBuffer.allocate(16384); |
- | public static void main(String args[]) throws Exception | + | public Server(int port) { |
- | + | this.port = port; | |
- | DatagramSocket serverSocket | + | new Thread(this).start(); |
- | + | } | |
- | byte[] bytesReceived | + | public void run() { |
- | byte[] bytesSent | + | try { |
- | + | // Instead of creating a ServerSocket, | |
- | + | // create a ServerSocketChannel | |
- | DatagramPacket receivePacket | + | ServerSocketChannel ssc = ServerSocketChannel.open(); |
- | // here we are waiting | + | // Set it to non-blocking, |
- | serverSocket.receive(receivePacket); | + | ssc.configureBlocking(false); |
- | + | // Get the Socket connected to this channel, and bind it | |
- | String textMessage | + | // to the listening port |
- | + | ServerSocket ss = ssc.socket(); | |
- | System.out.println(" | + | InetSocketAddress isa = new InetSocketAddress(port); |
- | + | ss.bind(isa); | |
- | InetAddress IPAddress = receivePacket.getAddress(); | + | // Create a new Selector for selecting |
- | int port = receivePacket.getPort(); | + | Selector selector = Selector.open(); |
- | + | // Register the ServerSocketChannel, | |
- | String upperCaseText = textMessage.toUpperCase(); | + | // listen for incoming connections |
- | bytesSent = upperCaseText.getBytes(); | + | ssc.register(selector, |
- | + | System.out.println(" | |
- | // send back | + | while (true) |
- | DatagramPacket sendPacket | + | // See if we've had any activity -- either |
- | serverSocket.send(sendPacket); | + | // an incoming connection, or incoming data on an |
- | serverSocket.close(); | + | // existing connection |
- | + | int num = selector.select(); | |
+ | // If we don't have any activity, loop around and wait | ||
+ | // again | ||
+ | if (num == 0) { | ||
+ | continue; | ||
+ | } | ||
+ | // Get the keys corresponding to the activity | ||
+ | // that has been detected, and process them | ||
+ | // one by one | ||
+ | Set keys = selector.selectedKeys(); | ||
+ | Iterator it = keys.iterator(); | ||
+ | while (it.hasNext()) { | ||
+ | // Get a key representing one of bits of I/O | ||
+ | // activity | ||
+ | SelectionKey key = (SelectionKey) it.next(); | ||
+ | // What kind of activity is it? | ||
+ | if ((key.readyOps() & SelectionKey.OP_ACCEPT) | ||
+ | System.out.println(" | ||
+ | // It's an incoming connection. | ||
+ | // Register this socket with the Selector | ||
+ | // so we can listen for input on it | ||
+ | Socket s = ss.accept(); | ||
+ | System.out.println(" | ||
+ | // Make sure to make it non-blocking, | ||
+ | // use a selector on it. | ||
+ | SocketChannel sc = s.getChannel(); | ||
+ | sc.configureBlocking(false); | ||
+ | // Register it with the selector, | ||
+ | sc.register(selector, | ||
+ | } else if ((key.readyOps() & SelectionKey.OP_READ) == SelectionKey.OP_READ) { | ||
+ | SocketChannel sc = null; | ||
+ | try { | ||
+ | // It's incoming data on a connection, so | ||
+ | // process it | ||
+ | sc = (SocketChannel) key.channel(); | ||
+ | boolean ok = processInput(sc); | ||
+ | // If the connection is dead, then remove it | ||
+ | // from the selector and close it | ||
+ | if (!ok) { | ||
+ | key.cancel(); | ||
+ | Socket s = null; | ||
+ | try { | ||
+ | s | ||
+ | s.close(); | ||
+ | } catch (IOException ie) { | ||
+ | System.err.println(" | ||
+ | + s + ": " + ie); | ||
+ | } | ||
+ | } | ||
+ | } catch (IOException ie) { | ||
+ | // On exception, remove this channel from the | ||
+ | // selector | ||
+ | key.cancel(); | ||
+ | try { | ||
+ | sc.close(); | ||
+ | } catch (IOException ie2) { | ||
+ | System.out.println(ie2); | ||
+ | } | ||
+ | System.out.println(" | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | // We remove the selected keys, because we've dealt | ||
+ | // with them. | ||
+ | keys.clear(); | ||
+ | } | ||
+ | } catch (IOException ie) { | ||
+ | System.err.println(ie); | ||
+ | } | ||
+ | } | ||
+ | // Do some cheesy encryption on the incoming data, | ||
+ | // and send it back out | ||
+ | private boolean processInput(SocketChannel sc) throws IOException { | ||
+ | buffer.clear(); | ||
+ | sc.read(buffer); | ||
+ | buffer.flip(); | ||
+ | // If no data, close the connection | ||
+ | if (buffer.limit() == 0) { | ||
+ | return false; | ||
+ | } | ||
+ | // Simple rot-13 encryption | ||
+ | for (int i = 0; i < buffer.limit(); ++i) { | ||
+ | byte b = buffer.get(i); | ||
+ | if ((b >= ' | ||
+ | b += 13; | ||
+ | } else if ((b >= ' | ||
+ | b -= 13; | ||
+ | } | ||
+ | buffer.put(i, b); | ||
+ | } | ||
+ | sc.write(buffer); | ||
+ | System.out.println(" | ||
+ | return true; | ||
+ | } | ||
+ | static public void main(String args[]) throws Exception { | ||
+ | new Server(4444); | ||
} | } | ||
} | } | ||
- | </code> | + | </sxh> |
tanszek/oktatas/iss_t/java_example_for_blocking_and_non-blocking_socket.1678034158.txt.gz · Last modified: 2023/03/05 16:35 by knehez