A kiválasztott változat és az aktuális verzió közötti különbségek a következők.
Következő változat | Előző változat | ||
tanszek:oktatas:tcp_socket_connection [2015/03/15 21:26] 127.0.0.1 külső szerkesztés |
tanszek:oktatas:tcp_socket_connection [2023/02/27 09:16] (aktuális) knehez [Exercise 1.] |
||
---|---|---|---|
Sor 1: | Sor 1: | ||
- | ==== 1.) Traditional socket based TCP server/client example ==== | + | ====== Socket client and server exercises ====== |
+ | ==== Exercise 1. ==== | ||
- | 1/a) Socket server source | + | Create a simplified FTP (file transport) client and server where the client can send or download text files from the server: |
- | import java.io.*; | + | == General use-cases == |
- | import java.net.*; | + | -) Client connects to the server and sends a 'file listing' message |
+ | -) Server sends back the list of the downloadable files | ||
+ | -) Client lists the files and asks the user what action they want to take? Upload or download? ('u' or 'd') | ||
+ | -) In both cases users must give the full file name with extension | ||
+ | -) The client sends the selected file to the server (upload) or downloads the selected file from the server to a specific directory. | ||
+ | |||
+ | |||
+ | == Server viewpoint == | ||
+ | -) After connecting, it reads the files from the /store subdirectory and sends the file names to the client after receiving the listing message. | ||
+ | -) We are waiting for the client's 'u' or 'd' operation | ||
+ | -) We get a filename from the client and if the action is 'd' (download), we read the file content and return its contents | ||
+ | -) If the operation is 'u' (upload), we open a new file with the specified name and wait for the data to be written to the file. | ||
+ | |||
+ | == Client viewpoint == | ||
+ | |||
+ | -) The client connects and waits for the list of files coming back and writes it to the console | ||
+ | -) We ask for the "u" or "d" key | ||
+ | -) Then we'll ask for the file-name as well. | ||
+ | -) The client reads the files from the /files folder, or creates the downloaded file here | ||
+ | -) If you press "d", it creates /files/ and writes data from the server | ||
+ | -) If you press "u", /files/ is sent to the server | ||
+ | |||
+ | ==== TCP style ==== | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | ==== 1.) Traditional blocked TCP based socket server class in Java ==== | ||
+ | |||
+ | === Socket server source code === | ||
+ | <code java> | ||
+ | import java.io.IOException; | ||
+ | import java.io.ObjectInputStream; | ||
+ | import java.io.ObjectOutputStream; | ||
+ | import java.net.ServerSocket; | ||
+ | import java.net.Socket; | ||
| | ||
- | public class Provider{ | + | public class Server { |
- | ServerSocket providerSocket; | + | ServerSocket providerSocket; |
- | Socket connection = null; | + | Socket connection = null; |
- | ObjectOutputStream out; | + | ObjectOutputStream out; |
- | ObjectInputStream in; | + | ObjectInputStream in; |
- | String message; | + | String message; |
- | Provider() {} | + | |
- | void run() { | + | Server() { |
- | try{ | + | } |
- | providerSocket = new ServerSocket(8080, 10); | + | |
- | connection = providerSocket.accept(); | + | void run() { |
- | out = new ObjectOutputStream(connection.getOutputStream()); | + | try { |
- | in = new ObjectInputStream(connection.getInputStream()); | + | // 1. create a socket server listening to port 8080 |
- | + | providerSocket = new ServerSocket(8080, 10); | |
- | do { | + | // 2. waiting for the connection (here we are waiting until next connection) |
- | try { | + | connection = providerSocket.accept(); |
- | message = (String)in.readObject(); | + | // 3. create Input and Output streams |
- | System.out.println("client>" + message); | + | out = new ObjectOutputStream(connection.getOutputStream()); |
- | if (message.equals("bye")) sendMessage("bye"); | + | in = new ObjectInputStream(connection.getInputStream()); |
- | } | + | // 4. socket communication |
- | catch(ClassNotFoundException classnot){ | + | do { |
- | System.err.println("Data received in unknown format"); | + | try { |
- | } | + | message = (String) in.readObject(); |
- | } while(!message.equals("bye")); | + | System.out.println("client>" + message); |
- | } | + | if (message.equals("bye")) { |
- | catch(IOException ioException){ | + | sendMessage("bye"); |
- | ioException.printStackTrace(); | + | } |
- | } | + | } catch (ClassNotFoundException classnot) { |
- | finally{ | + | System.err.println("Data received in unknown format"); |
- | try { | + | } |
- | in.close(); | + | } while (!message.equals("bye")); |
- | out.close(); | + | } catch (IOException ioException) { |
- | providerSocket.close(); | + | ioException.printStackTrace(); |
- | } | + | } finally { |
- | catch(IOException ioException){ | + | // 4: close connection |
- | ioException.printStackTrace(); | + | try { |
- | } | + | in.close(); |
- | } | + | out.close(); |
- | } | + | providerSocket.close(); |
- | + | } catch (IOException ioException) { | |
- | void sendMessage(String msg) { | + | ioException.printStackTrace(); |
- | try { | + | } |
- | out.writeObject(msg); | + | } |
- | out.flush(); | + | } |
- | System.out.println("server>" + msg); | + | |
- | } | + | void sendMessage(String msg) { |
- | catch(IOException ioException){ | + | try { |
- | ioException.printStackTrace(); | + | out.writeObject(msg); |
- | } | + | out.flush(); |
- | } | + | System.out.println("server>" + msg); |
- | + | } catch (IOException ioException) { | |
- | public static void main(String args[]) { | + | ioException.printStackTrace(); |
- | Provider server = new Provider(); | + | } |
- | while(true){ | + | } |
- | server.run(); | + | |
- | } | + | public static void main(String args[]) { |
- | } | + | Server server = new Server(); |
- | } | + | while (true) { |
+ | server.run(); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | === Socket client source === | ||
+ | <code java> | ||
+ | import java.io.IOException; | ||
+ | import java.io.ObjectInputStream; | ||
+ | import java.io.ObjectOutputStream; | ||
+ | import java.net.Socket; | ||
+ | import java.net.UnknownHostException; | ||
+ | |||
+ | public class Client { | ||
+ | Socket requestSocket; | ||
+ | ObjectOutputStream out; | ||
+ | ObjectInputStream in; | ||
+ | String message; | ||
+ | |||
+ | Client() { | ||
+ | } | ||
+ | |||
+ | void run() { | ||
+ | try { | ||
+ | // 1. try to connect to the socket: localhost:8080 | ||
+ | requestSocket = new Socket("localhost", 8080); | ||
+ | // 2. Input and Output streams | ||
+ | out = new ObjectOutputStream(requestSocket.getOutputStream()); | ||
+ | in = new ObjectInputStream(requestSocket.getInputStream()); | ||
+ | // 3: communications | ||
+ | do { | ||
+ | try { | ||
+ | sendMessage("Hello server"); | ||
+ | sendMessage("bye"); | ||
+ | message = (String) in.readObject(); | ||
+ | } catch (Exception e) { | ||
+ | System.err.println("data received in unknown format"); | ||
+ | } | ||
+ | } while (!message.equals("bye")); | ||
+ | } catch (UnknownHostException unknownHost) { | ||
+ | System.err.println("You are trying to connect to an unknown host!"); | ||
+ | } catch (IOException ioException) { | ||
+ | ioException.printStackTrace(); | ||
+ | } finally { | ||
+ | // 4: close connection | ||
+ | try { | ||
+ | in.close(); | ||
+ | out.close(); | ||
+ | requestSocket.close(); | ||
+ | } catch (IOException ioException) { | ||
+ | ioException.printStackTrace(); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | void sendMessage(String msg) { | ||
+ | try { | ||
+ | out.writeObject(msg); | ||
+ | out.flush(); | ||
+ | System.out.println("client>" + msg); | ||
+ | } catch (IOException ioException) { | ||
+ | ioException.printStackTrace(); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | public static void main(String args[]) { | ||
+ | Client client = new Client(); | ||
+ | client.run(); | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | ==== Traditional UDP style ==== | ||
- | 1/b.) Client source | + | The following Agent sends a message and waits for a response on port 8080, also with UDP. In the Eclipse IDE, the text you type on the console can be sent by pressing ctrl+z |
+ | == Exercise 2. == | ||
+ | Modify the code so that you can transfer a burned-in name and existing text or image file larger than 2 kbytes and verify that it was successfully sent. | ||
- | import java.io.*; | + | <code java> |
- | import java.net.*; | + | package org.ait; |
- | + | ||
- | public class Requester{ | + | import java.io.BufferedReader; |
- | Socket requestSocket; | + | import java.io.InputStreamReader; |
- | ObjectOutputStream out; | + | import java.net.DatagramPacket; |
- | ObjectInputStream in; | + | import java.net.DatagramSocket; |
- | String message; | + | import java.net.InetAddress; |
- | Requester(){} | + | |
- | void run() { | + | public class UDPClient { |
- | try{ | + | public static void main(String args[]) throws Exception { |
- | requestSocket = new Socket("localhost", 8080); | + | BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in)); |
- | out = new ObjectOutputStream(requestSocket.getOutputStream()); | + | DatagramSocket clientSocket = new DatagramSocket(); |
- | in = new ObjectInputStream(requestSocket.getInputStream()); | + | InetAddress IPAddress = InetAddress.getByName("localhost"); |
- | do { | + | |
- | try { | + | byte[] sendData = new byte[1024]; |
- | sendMessage("Hello szerver"); | + | byte[] receiveData = new byte[1024]; |
- | sendMessage("bye"); | + | |
- | message = (String)in.readObject(); | + | String sentence = inFromUser.readLine(); |
- | } | + | sendData = sentence.getBytes(); |
- | catch(Exception e){ | + | |
- | System.err.println("data received in unknown format"); | + | DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, 8080); |
- | } | + | clientSocket.send(sendPacket); |
- | } while(!message.equals("bye")); | + | |
- | } | + | DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length); |
- | catch(UnknownHostException unknownHost){ | + | clientSocket.receive(receivePacket); |
- | System.err.println("You are trying to connect to an unknown host!"); | + | String modifiedSentence = new String(receivePacket.getData()); |
- | } | + | |
- | catch(IOException ioException){ | + | System.out.println("converted:" + modifiedSentence); |
- | ioException.printStackTrace(); | + | clientSocket.close(); |
- | } | + | |
- | finally{ | + | |
- | try{ | + | |
- | in.close(); | + | |
- | out.close(); | + | |
- | requestSocket.close(); | + | |
- | } | + | |
- | catch(IOException ioException){ | + | |
- | ioException.printStackTrace(); | + | |
- | } | + | |
- | } | + | |
} | } | ||
- | | ||
- | void sendMessage(String msg) { | ||
- | try { | ||
- | out.writeObject(msg); | ||
- | out.flush(); | ||
- | System.out.println("client>" + msg); | ||
- | } | ||
- | catch(IOException ioException){ | ||
- | ioException.printStackTrace(); | ||
- | } | ||
} | } | ||
- | + | </code> | |
- | public static void main(String args[]) { | + | |
- | Requester client = new Requester(); | + | 2.b) 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. |
- | client.run(); | + | |
+ | <code 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, bytesReceived.length); | ||
+ | // here we are waiting for the packets | ||
+ | serverSocket.receive(receivePacket); | ||
+ | |||
+ | String textMessage = new String(receivePacket.getData()); | ||
+ | |||
+ | System.out.println("I got: " + textMessage); | ||
+ | |||
+ | InetAddress IPAddress = receivePacket.getAddress(); | ||
+ | int port = receivePacket.getPort(); | ||
+ | |||
+ | String upperCaseText = textMessage.toUpperCase(); | ||
+ | bytesSent = upperCaseText.getBytes(); | ||
+ | |||
+ | // send back | ||
+ | DatagramPacket sendPacket = new DatagramPacket(bytesSent, bytesSent.length, IPAddress, port); | ||
+ | serverSocket.send(sendPacket); | ||
+ | serverSocket.close(); | ||
+ | |||
} | } | ||
} | } | ||
+ | </code> |