SOCKET PROGRAMMING WITH MOBILE SOCKET CLIENT DEARTMENT OF COMPUTER SCIENCE IOWA STATE UNIVERSITY BASICS OF ANDROID SOCKET PROGRAMMING A socket is a common interface for performing network communication. Underneath the hood, Android’s HTTP client library is using sockets to send and receive data. Android Sockets are the same as Java Sockets. The package java.net provides support for sockets programming (and more). JAVA SOCKET PROGRAMMING Classes defined in this package are: InetAddress Socket ServerSocket DatagramSocket DatagramPacket InetAddress CLASS Static methods you can use to create new InetAddress objects. getByName(String host) getAllByName(String host) getLocalHost() Example Use of the class: Code: try { InetAddress a = InetAddress.getByName(hostname); System.out.println(hostname + ":" a.getHostAddress()); } catch (UnknownHostException e) { System.out.println("No address found for " + hostname); } Output: www.yahoo.com:209.131.36.158 Socket CLASS A Socket class defines active TCP sockets only client sockets socket returned by accept(); Constructor and Methods Constructor: Creates a stream socket and connects it to the specified port number on the named host. Following are different constructors: Socket(InetAddress server, int port); Socket(InetAddress server, int port,InetAddress local, int localport); Socket(String hostname, int port); close() :Closes the Socket connection and releases all associated resources. Thus a Client Socket is created as follows: Socket socclient=new Socket(server_ip_address,server_port_number); SocketServer CLASS A ServerSocket class defines a Server Socket. Passive sockets are supported by this class. Constructor and Methods: Constructor: Creates a server socket and binds it to the specified local port number, with the specified backlog. The following are different constructors: ServerSocket(int port); ServerSocket(int port, int backlog); ServerSocket(int port, int backlog, InetAddress bindAddr); Socket Accept(): Listens for a connection to be made to this socket and accepts it. This method blocks until a connection is made. This is a method of the SocketServer Class however the object instance returned by this method is of the Socket class. close(): Closes the Socket connection and releases all associated resources. A Server Socket can be created as follows: ServerSocket server_sock = new ServerSocket(server_port_number); TCP Socket Client Server Communication UDP is Connectionless and unreliable service. There isn’t an initial handshaking phase. Transmitted data may be received out of order, or lost. UDP Sockets Socket Programming with UDP No need for a welcoming socket. No streams are attached to the sockets. The sending hosts creates “packets” by attaching the IP destination address and port number to each batch of bytes and the receiving process must unravel to received packet to obtain the packet’s information bytes. DatagramSocket class is used to create a UDP socket. DatagramSocket(); DatagramSocket(int port); DatagramSocket(int port, InetAddress a); DatagramPacket class needed to specify the payload. DatagramPacket( byte[] buf, int len, InetAddress a, int port); UDP Socket Client Server Communication import java.io.*; import java.net.*; class UDPClient { public static void main(String args[]) throws Exception { BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in)); Example UDP Client DatagramSocket clientSocket = new DatagramSocket(); InetAddress IPAddress = InetAddress.getByName("hostname"); byte[] sendData = new byte[1024]; byte[] receiveData = new byte[1024]; String sentence = inFromUser.readLine(); sendData = sentence.getBytes(); DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, 9876); clientSocket.send(sendPacket); DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length); Example UDP Client clientSocket.receive(receivePacket); String modifiedSentence = new String(receivePacket.getData()); System.out.println("FROM SERVER:" + modifiedSentence); clientSocket.close(); } } import java.io.*; import java.net.*; class UDPServer { public static void main(String args[]) throws Exception { Example UDP Server DatagramSocket serverSocket = new DatagramSocket(9876); byte[] receiveData = new byte[1024]; byte[] sendData = new byte[1024]; while(true) { DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length); serverSocket.receive(receivePacket); String sentence = new String(receivePacket.getData()); InetAddress IPAddress = receivePacket.getAddress(); int port = receivePacket.getPort(); String capitalizedSentence = sentence.toUpperCase(); sendData = capitalizedSentence.getBytes(); Example UDP Server DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, port); serverSocket.send(sendPacket); } } } Socket I/O is based on the Java I/O support in the package java.io Socket I/O Once a Socket is created data can be transmitted using Inputstreams and Outputstreams. InputStream and OutputStream are abstract classes. An InputStream is a stream of incoming byte data. An InputStream can be obtained from a Socket by using the getInputStream() method. InputStream In order to read from a stream, you must create a byte buffer to read in data.Each call to read on an InputStream fills your buffer with data and returns the number of bytes read. Example use of InputStream: BufferedReader in=new BufferedReader(new InputStreamReader(socclient.getInputStream())); String data=in.readLine(); An OutputStream is a stream of outgoing byte data An OutputStream can be obtained from a Socket by using the getOutputStream() method. You can write data to a stream by passing in a byte buffer of data. OutputStream You should use the flush() method if you want to make sure that the data you have written has been output to disk or sent to the other end of the socket. Eg: PrintWriter out = PrintWriter(socclient.getOutputStream(), true); new SCENARIO Consider a Java Socket Server and a Mobile Application Client. Consider the Mobile Application to run an Android OS. Let us look at some very simple examples to create an Android Application that works as a socket client. Example 1: Consider A simple Socket Server which receives a text file’s name with path from the Socket client and replies saying weather the file exists in the given path or not. If the file exists, it retrieves the contents of the text file. Example 2: Consider A simple Socket server which receives a string and replies with the count of the number of occurrences of the letter ‘s’ in the string. The Complete Code of these examples is available as part of the module. Implement a Java Socket Server irrespective of the android nature of the client. EXAMPLE I JAVA SOCKET SERVER The Following code snippet creats a ServerSocket and calls the accept() blocking call to wait for connection. public class SockServer { public static void main(String[] args) throws Exception { System.out.println(“ The File Retrieval server is running."); int clientNumber = 0; ServerSocket listener = new ServerSocket(9898); Create Socket try { while (true) { new Finder(listener.accept(), clientNumber++).start(); Wait for Client Connection } } finally { and create a new thread for each client listener.close(); } } .. The following code snippet defines the Finder Class that stores the information about Each Socket Client connection. .. EXAMPLE I JAVA SOCKET SERVER private static class Finder extends Thread { private Socket socket; private int clientNumber; Extends Thread Class public Finder(Socket socket, int clientNumber) { this.socket = socket; this.clientNumber = clientNumber; log("New connection with client# " + clientNumber + " at " + socket); } .. EXAMPLE I JAVA SOCKET SERVER public void run() { try { BufferedReader in = new BufferedReader( new InputStreamReader(socket.getInputStream())); PrintWriter out = new PrintWriter(socket.getOutputStream(), true); while (true) { String input = in.readLine(); if (input == null || input.equals(".")) { break; } CheckforFile cf = new CheckforFile(); int exists = cf.fileExists(input); Input Stream Output Stream Get file path from Socket Instantiate CheckforFile object who’s fileExists() function returns 1 if file exists and 0 otherwise EXAMPLE I JAVA SOCKET SERVER File dir = new File(input) if(exists==1) { System.out.println("The file exists"); BufferedReader br = new BufferedReader(new FileReader(dir)); try { StringBuilder sb = new StringBuilder(); String line = br.readLine(); Send data to Client which specifies if the file exits, the contents of while (line != null) { the file. sb.append(line); sb.append(System.lineSeparator()); line = br.readLine(); } String everything = sb.toString(); out.println("Hello, client #" + clientNumber + ". The file "+input+" exists"+"The contents of the file are:"+everything); } finally { br.close(); } } else { out.println("The file "+input+" does not exist"); Send data to client specifying that the file does not exist. System.out.println("The file does not exist"); } EXAMPLE I JAVA SOCKET SERVER } } catch (IOException e) { log("Error handling client# " + clientNumber + ": " + Handle Exceptions e); } finally { try { socket.close(); } catch (IOException e) { log("Couldn't close a socket, what's going on?"); } log("Connection with client# " + clientNumber + " closed"); } } private void log(String message) { System.out.println(message); } } } Close Socket Handle Exceptions The Android Client is a simple Java Client with additional handlers for updating the User Interface. EXAMPLE I ANDROID SOCKET CLIENT In Android we use a PrintWriter to output data to the socket server because it writes characters as opposed to a PrintStream which writes bytes. Use a Handler to communicate with the UI thread. The Android User Interface is updated using a UI thread and hence the Socket thread which is a Background thread requires a Handler object to update the UI. AsyncTask can be used instead of Threads as they require lesser maintenance. The basic example given however uses Threads for simplicity. Create an Android Application with a Blank Activity. If you are new to Android Programming refer to the Modules on Basic Android Programming. Layout: EXAMPLE I ANDROID SOCKET CLIENT Create a Simple Layout with a TextField reading “Text File Path”, an EditText field that takes the path input and a Button “Find”. Add a ScrollView to the Layout by adding the following code to activity_main.xml under <Project_folder> -> res -> layout. <ScrollView android:id="@+id/scrollView1" android:layout_width="fill_parent" android:layout_height="200dp"> <LinearLayout android:id="@+id/linearLayout2" android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="vertical"> </LinearLayout> </ScrollView> Add a button on click Method inside the Main Activity Class of the Application. public void searchFile(View v) { EXAMPLE I ANDROID SOCKET CLIENT this.editText= (EditText)findViewById(R.id.editText1); Get the View by ID and get the final String value = editText.getText().toString(); contents of the field displayMessage("Searching for file: "+value); this method updates the UI tclient=new Thread(new Runnable(){ public void run() { create a thread try { displayMessage("Socket being Created.. "); socclient=new Socket(B); create socket PrintWriter out = new PrintWriter(socclient.getOutputStream(), true); if(value!=null) { out.println(value); send the filepath to the server Output Stream Message servermsg=Message.obtain(); BufferedReader in=new BufferedReader(new InputStreamReader(socclient.getInputStream())); InputStream String data=in.readLine(); Read response from server servermsg.obj="Server Response: "+data; handler.sendMessage(servermsg); EXAMPLE I ANDROID SOCKET CLIENT Use the handler to update UI in.close(); } close input and output streams. out.close(); } catch (UnknownHostException e) { e.printStackTrace(); }catch (IOException e) { e.printStackTrace(); } } }); tclient.start(); } handle exceptions public void displayMessage(String msg) the string parameter as a textview item { into the scrollview of your application this.scrollView = (ScrollView) findViewById(R.id.scrollView1); this.linearLayout = (LinearLayout) findViewById(R.id.linearLayout2); TextView tx = new TextView(this); EXAMPLE I ANDROID SOCKET CLIENT tx.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); tx.setText(msg); this.linearLayout.addView(tx); } Handler handler=new Handler() { public void handleMessage(Message msg) override the handMessage method { displayMessage(msg.obj.toString()); } }; EXAMPLE I Output This is a Screenshot of the Application running in the Android Device with the response from the server containing the contents of the text file. EXAMPLE II Output Screenshot of the Application running in the Android Device with the response from the server containing the number of occurrences of the letter ‘s’ in the entered string. THANK YOU!