Advanced Java
Advanced Java
Advanced Java
Advanced
Java
SE
Multitasking: Ability to execute more than one task at the same time is known as multitasking.
Multithreading: We already discussed about it. It is a process of executing multiple threads
simultaneously. Multithreading is also known as Thread-based Multitasking.
Multiprocessing: It is same as multitasking, however in multiprocessing more than one CPUs are
involved. On the other hand one CPU is involved in multitasking.
Parallel Processing: It refers to the utilization of multiple CPUs in a single computer system.
• Each process has an address in memory. In other words, each process allocates a
separate memory area.
• A process is heavyweight.
• Cost of communication between the process is high.
• Switching from one process to another requires some time for saving and loading
registers, memory maps, updating lists, etc.
2) Thread-based Multitasking (Multithreading)
1
What is Thread in java?
A thread is a lightweight subprocess, the smallest unit of processing. It is a separate path of
execution.
Threads are independent. If there occurs exception in one thread, it doesn't affect other threads.
It uses a shared memory area.
As shown in the above figure, a thread is executed inside the process. There is context-switching
between the threads. There can be multiple processes inside the OS, and one process can have
multiple threads.
2
Life Cycle of a Thread
A thread goes through various stages in its life cycle. For example, a thread is born, started, runs,
and then dies. The following diagram shows the complete life cycle of a thread.
• New − A new thread begins its life cycle in the new state. It remains in this state until the
program starts the thread. It is also referred to as a born thread.
• Runnable − After a newly born thread is started, the thread becomes runnable. A thread
in this state is considered to be executing its task.
• Waiting − Sometimes, a thread transitions to the waiting state while the thread waits for
another thread to perform a task. A thread transitions back to the runnable state only
when another thread signals the waiting thread to continue executing.
• Timed Waiting − A runnable thread can enter the timed waiting state for a specified
interval of time. A thread in this state transitions back to the runnable state when that
time interval expires or when the event it is waiting for occurs.
• Terminated (Dead) − A runnable thread enters the terminated state when it completes
its task or otherwise terminates.
3
Creating a thread in Java
There are two ways to create a thread in Java:
1) By extending Thread class.
2) By implementing Runnable interface.
Before we begin with the programs(code) of creating threads, let’s have a look at these methods
of Thread class. We have used few of these methods in the example below.
1) getName(): It is used for Obtaining a thread’s name
2) getPriority(): Obtain a thread’s priority
3) isAlive(): Determine if a thread is still running
4) join(): Wait for a thread to terminate
5) run(): Entry point for the thread
6) sleep(): suspend a thread for a period of time
7) start(): start a thread by calling its run() method
4
// Displaying the thread that is running
System.out.println ("Thread " +
Thread.currentThread().getId() +
" is running");
}
catch (Exception e)
{
// Throwing an exception
System.out.println ("Exception is caught");
}
}
}
// Main Class
public class Multithread
{
public static void main(String[] args)
{
int n = 8; // Number of threads
for (int i=0; i<8; i++)
{
MultithreadingDemo object = new MultithreadingDemo();
object.start();
}
}
}
5
Output :
Thread 8 is running
Thread 9 is running
Thread 10 is running
Thread 11 is running
Thread 12 is running
Thread 13 is running
Thread 14 is running
Thread 15 is running
6
" is running");
}
catch (Exception e)
{
// Throwing an exception
System.out.println ("Exception is caught");
}
}
}
// Main Class
class Multithread
{
public static void main(String[] args)
{
int n = 8; // Number of threads
for (int i=0; i<8; i++)
{
Thread object = new Thread(new MultithreadingDemo());
object.start();
}
}
}
7
Output :
Thread 8 is running
Thread 9 is running
Thread 10 is running
Thread 11 is running
Thread 12 is running
Thread 13 is running
Thread 14 is running
Thread 15 is running
8
Can we start a thread twice in Java?
The answer is no, once a thread is started, it can never be started again. Doing so will throw an
IllegalThreadStateException. Lets have a look at the below code:
}
public static void main(String args[]){
Thread th1 = new Thread(new ThreadTwiceExample(), "th1");
th1.start();
th1.start();
}
}
Output:
Exception in thread "main" th1 is executing.
java.lang.IllegalThreadStateException
As you observe the first call to start() resulted in execution of run() method, however the
exception got thrown when we tried to call the start() second time.
9
Thread priorities
• Thread priorities are the integers which decide how one thread should be treated with
respect to the others.
• Thread priority decides when to switch from one running thread to another, process is
called context switching
• A thread can voluntarily release control and the highest priority thread that is ready to
run is given the CPU.
• A thread can be preempted by a higher priority thread no matter what the lower priority
thread is doing. Whenever a higher priority thread wants to run it does.
• To set the priority of the thread setPriority() method is used which is a method of the
class Thread Class.
• In place of defining the priority in integers, we can use MIN_PRIORITY, NORM_PRIORITY
or MAX_PRIORITY.
10
System.out.println("t1 thread priority : " +
t1.getPriority()); // Default 5
System.out.println("t2 thread priority : " +
t2.getPriority()); // Default 5
System.out.println("t3 thread priority : " +
t3.getPriority()); // Default 5
t1.setPriority(2);
t2.setPriority(5);
t3.setPriority(8);
// Main thread
System.out.print(Thread.currentThread().getName());
System.out.println("Main thread priority : "
+ Thread.currentThread().getPriority());
11
+ Thread.currentThread().getPriority());
}
}
Output:
t1 thread priority : 5
t2 thread priority : 5
t3 thread priority : 5
t1 thread priority : 2
t2 thread priority : 5
t3 thread priority : 8
Main thread priority : 5
Main thread priority : 10
Note:
• Thread with highest priority will get execution chance prior to other threads. Suppose
there are 3 threads t1, t2 and t3 with priorities 4, 6 and 1. So, thread t2 will execute first
based on maximum priority 6 after that t1 will execute and then t3.
• Default priority for main thread is always 5, it can be changed later. Default priority for all
other threads depends on the priority of parent thread.
12
{
System.out.println("Inside run method");
}
public static void main(String[]args)
{
// main thread priority is 6 now
Thread.currentThread().setPriority(6);
• If two threads have same priority then we can’t expect which thread will execute first. It
depends on thread scheduler’s algorithm(Round-Robin, First Come First Serve, etc)
• If we are using thread priority for thread scheduling then we should always keep in mind
that underlying platform should provide support for scheduling based on thread priority.
13
Methods: isAlive() and join()
• In all the practical situations main thread should finish last else other threads which have
spawned from the main thread will also finish.
• To know whether the thread has finished we can call isAlive() on the thread which returns
true if the thread is not finished.
• Another way to achieve this by using join() method, this method when called from the
parent thread makes parent thread wait till child thread terminates.
• These methods are defined in the Thread class.
• We have used isAlive() method in the above examples too.
14
System.out.println("before starting thread isAlive: "+t1.isAlive());
t1.start();
System.out.println("after starting thread isAlive: "+t1.isAlive());
}
}
Output:
before starting thread isAlive: false
after starting thread isAlive: true
is run() method isAlive true
Here is a simple example showing usage of Thread join methods. The goal of the program is to
make sure main is the last thread to finish and third thread starts only when first one is dead.
public class ThreadJoinExample {
public static void main(String[] args) {
Thread t1 = new Thread(new MyRunnable(), "t1");
Thread t2 = new Thread(new MyRunnable(), "t2");
15
Thread t3 = new Thread(new MyRunnable(), "t3");
t1.start();
//start second thread after waiting for 2 seconds or if it's dead
try {
t1.join(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
t2.start();
t3.start();
16
e.printStackTrace();
}
@Override
public void run() {
System.out.println("Thread started:::"+Thread.currentThread().getName());
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread ended:::"+Thread.currentThread().getName());
}
17
Thread started:::t3
Thread ended:::t2
Thread ended:::t3
All threads are dead, exiting main thread
Synchronization
• Multithreading introduces asynchronous behavior to the programs. If a thread is writing
some data another thread may be reading the same data at that time. This may bring
inconsistency.
• When two or more threads need access to a shared resource there should be some way
that the resource will be used only by one resource at a time. The process to achieve this
is called synchronization.
• To implement the synchronous behavior java has synchronous method. Once a thread is
inside a synchronized method, no other thread can call any other synchronized method
on the same object. All the other threads then wait until the first thread come out of the
synchronized block.
• When we want to synchronize access to objects of a class which was not designed for the
multithreaded access and the code of the method which needs to be accessed
synchronously is not available with us, in this case we cannot add the synchronized to the
appropriate methods. In java we have the solution for this, put the calls to the methods
(which needs to be synchronized) defined by this class inside a synchronized block in
following manner.
Java provides a way of creating threads and synchronizing their task by using synchronized blocks.
Synchronized blocks in Java are marked with the synchronized keyword. A synchronized block in
Java is synchronized on some object. All synchronized blocks synchronized on the same object
can only have one thread executing inside them at a time. All other threads attempting to enter
the synchronized block are blocked until the thread inside the synchronized block exits the block.
18
// whose lock associates with the monitor.
// The code is said to be synchronized on
// the monitor object
synchronized(sync_object)
{
// Access shared variables and other
// shared resources
}
This synchronization is implemented in Java with a concept called monitors. Only one thread can
own a monitor at a given time. When a thread acquires a lock, it is said to have entered the
monitor. All other threads attempting to enter the locked monitor will be suspended until the
first thread exits the monitor.
Following is an example of multi threading with synchronized.
// A Java program to demonstrate working of
// synchronized.
import java.io.*;
import java.util.*;
19
catch (Exception e)
{
System.out.println("Thread interrupted.");
}
System.out.println("\n" + msg + "Sent");
}
}
20
{
// synchronizing the snd object
sender.send(msg);
}
}
}
// Driver class
class SyncDemo
{
public static void main(String args[])
{
Sender snd = new Sender();
ThreadedSend S1 =
new ThreadedSend( " Hi " , snd );
ThreadedSend S2 =
new ThreadedSend( " Bye " , snd );
21
}
catch(Exception e)
{
System.out.println("Interrupted");
}
}
}
Output:
Sending Hi
Hi Sent
Sending Bye
Bye Sent
22
Inter-thread Communication
We have few methods through which java threads can communicate with each other. These
methods are wait(), notify(), notifyAll(). All these methods can only be called from within a
synchronized method.
1) To understand synchronization java has a concept of monitor. Monitor can be thought of
as a box which can hold only one thread. Once a thread enters the monitor all the other
threads have to wait until that thread exits the monitor.
2) wait() tells the calling thread to give up the monitor and go to sleep until some other
thread enters the same monitor and calls notify().
3) notify() wakes up the first thread that called wait() on the same object.
notifyAll() wakes up all the threads that called wait() on the same object. The highest
priority thread will run first.
if(this.amount<amount){
System.out.println("Less balance; waiting for deposit...");
try{wait();}catch(Exception e){}
}
this.amount-=amount;
System.out.println("withdraw completed...");
}
23
System.out.println("going to deposit...");
this.amount+=amount;
System.out.println("deposit completed... ");
notify();
}
}
class Test{
public static void main(String args[]){
final Customer c=new Customer();
new Thread(){
public void run(){c.withdraw(15000);}
}.start();
new Thread(){
public void run(){c.deposit(10000);}
}.start();
}}
24
Interrupting a Thread:
If any thread is in sleeping or waiting state (i.e. sleep() or wait() is invoked), calling the interrupt()
method on the thread, breaks out the sleeping or waiting state throwing InterruptedException.
If the thread is not in the sleeping or waiting state, calling the interrupt() method performs
normal behaviour and doesn't interrupt the thread but sets the interrupt flag to true. Let's first
see the methods provided by the Thread class for thread interruption.
In this example, after interrupting the thread, we are propagating it, so it will stop working. If we
don't want to stop the thread, we can handle it where sleep() or wait() method is invoked.
Let's first see the example where we are propagating the exception.
class TestInterruptingThread1 extends Thread{
public void run(){
try{
Thread.sleep(1000);
System.out.println("task");
}catch(InterruptedException e){
throw new RuntimeException("Thread interrupted..."+e);
}
}
}
25
Output:Exception in thread-0
java.lang.RuntimeException: Thread interrupted...
java.lang.InterruptedException: sleep interrupted
at A.run(A.java:7)
In this example, after interrupting the thread, we handle the exception, so it will break out the
sleeping but will not stop working.
class TestInterruptingThread2 extends Thread{
public void run(){
try{
Thread.sleep(1000);
System.out.println("task");
}catch(InterruptedException e){
System.out.println("Exception handled "+e);
}
System.out.println("thread is running...");
}
t1.interrupt();
}
}
26
Output:Exception handled
java.lang.InterruptedException: sleep interrupted
thread is running...
If thread is not in sleeping or waiting state, calling the interrupt() method sets the interrupted
flag to true that can be used to stop the thread by the java programmer later.
class TestInterruptingThread3 extends Thread{
public void run(){
for(int i=1;i<=5;i++)
System.out.println(i);
}
t1.interrupt();
}
}
Output:1
2
3
4
5
27
Thread Deadlock
Deadlock describes a situation where two or more threads are blocked forever, waiting for each
other. Deadlock occurs when multiple threads need the same locks but obtain them in different
order. A Java multithreaded program may suffer from the deadlock condition because the
synchronized keyword causes the executing thread to block while waiting for the lock, or
monitor, associated with the specified object. Here is an example.
try { Thread.sleep(10); }
catch (InterruptedException e) {}
System.out.println("Thread 1: Waiting for lock 2...");
synchronized (Lock2) {
28
System.out.println("Thread 1: Holding lock 1 & 2...");
}
}
}
}
private static class ThreadDemo2 extends Thread {
public void run() {
synchronized (Lock2) {
System.out.println("Thread 2: Holding lock 2...");
try { Thread.sleep(10); }
catch (InterruptedException e) {}
System.out.println("Thread 2: Waiting for lock 1...");
synchronized (Lock1) {
System.out.println("Thread 2: Holding lock 1 & 2...");
}
}
}
}
}
When you compile and execute the above program, you find a deadlock situation and following
is the output produced by the program −
Output
Thread 1: Holding lock 1...
Thread 2: Holding lock 2...
Thread 1: Waiting for lock 2...
29
Thread 2: Waiting for lock 1...
The above program will hang forever because neither of the threads in position to proceed and
waiting for each other to release the lock, so you can come out of the program by pressing
CTRL+C.
try {
Thread.sleep(10);
} catch (InterruptedException e) {}
30
System.out.println("Thread 1: Waiting for lock 2...");
synchronized (Lock2) {
System.out.println("Thread 1: Holding lock 1 & 2...");
}
}
}
}
private static class ThreadDemo2 extends Thread {
public void run() {
synchronized (Lock1) {
System.out.println("Thread 2: Holding lock 1...");
try {
Thread.sleep(10);
} catch (InterruptedException e) {}
System.out.println("Thread 2: Waiting for lock 2...");
synchronized (Lock2) {
System.out.println("Thread 2: Holding lock 1 & 2...");
}
}
}
}
}
So just changing the order of the locks prevent the program in going into a deadlock situation
and completes with the following result −
31
Output
Thread 1: Holding lock 1...
Thread 1: Waiting for lock 2...
Thread 1: Holding lock 1 & 2...
Thread 2: Holding lock 1...
Thread 2: Waiting for lock 2...
Thread 2: Holding lock 1 & 2...
The above example is to just make the concept clear, however, it is a complex concept and you
should deep dive into it before you develop your applications to deal with deadlock situations.
32
Chapter 2
Networks
A network is a collection of computers and other devices that can send data to and receive data
from one another, more or less in real time. A network is often connected by wires, and the bits
of data are turned into electromagnetic waves that move through the wires. However, wireless
networks transmit data using radio waves; and most longdistance transmissions are now carried
over fiber-optic cables that send light waves through glass filaments.
33
different level of abstraction between the physical hardware (i.e., the wires and electricity) and
the information being transmitted. In theory, each layer only talks to the layers immediately
above and immediately below it. Separating the network into layers lets you modify or even
replace the software in one layer without affecting the others, as long as the interfaces between
the layers stay the same.
There are several different layer models, each organized to fit the needs of a particular kind of
network. This book uses the standard TCP/IP four-layer model appropriate for the Internet,
shown in Figure. In this model, applications like Firefox and Warcraft run in the application layer
and talk only to the transport layer. The transport layer talks only to the application layer and the
Internet layer. The Internet layer in turn talks only to the host-to-network layer and the transport
layer, never directly to the application layer. The host-to-network layer moves the data across
the wires, fiber-optic cables, or other medium to the host-to-network layer on the remote
system, which then moves the data up the layers to the application on the remote system.
34
The layers of a network
35
Layered connections through a proxy server
36
A client/server connection
37
Sockets for Clients
Data is transmitted across the Internet in packets of finite size called datagrams. Each datagram
contains a header and a payload. The header contains the address and port to which the packet
is going, the address and port from which the packet came, a checksum to detect data corruption,
and various other housekeeping information used to ensure reliable transmission. The payload
contains the data itself. However, because datagrams have a finite length, it’s often necessary to
split the data across multiple packets and reassemble it at the destination. It’s also possible that
one or more packets may be lost or corrupted in transit and need to be retransmitted or that
packets arrive out of order and need to be reordered. Keeping track of this—splitting the data
into packets, generating headers, parsing the headers of incoming packets, keeping track of what
packets have and haven’t been received, and so on—is a lot of work and requires a lot of intricate
code.
Fortunately, you don’t have to do the work yourself. Sockets allow the programmer to treat a
network connection as just another stream onto which bytes can be written and from which
bytes can be read. Sockets shield the programmer from low-level details of the network, such as
error detection, packet sizes, packet splitting, packet retransmission, network addresses, and
more.
Using Sockets
A socket is a connection between two hosts. It can perform seven basic operations:
• Connect to a remote machine
• Send data
• Receive data
• Close a connection
• Bind to a port
• Listen for incoming data
• Accept connections from remote machines on the bound port
Java’s Socket class, which is used by both clients and servers, has methods that correspond to
the first four of these operations. The last three operations are needed only by servers, which
wait for clients to connect to them. They are implemented by the ServerSocket class, which is
discussed in the next chapter. Java programs normally use client sockets in the following fashion:
• The program creates a new socket with a constructor.
38
• The socket attempts to connect to the remote host.
Once the connection is established, the local and remote hosts get input and output streams
from the socket and use those streams to send data to each other. This connection is full-duplex.
Both hosts can send and receive data simultaneously. What the data means depends on the
protocol; different commands are sent to an FTP server than to an HTTP server. There will
normally be some agreed-upon handshaking followed by the transmission of data from one to
the other.
When the transmission of data is complete, one or both sides close the connection. Some
protocols, such as HTTP 1.0, require the connection to be closed after each request is serviced.
Others, such as FTP and HTTP 1.1, allow multiple requests to be processed in a single connection.
1 /*
2 * To change this license header, choose License Headers in Project Properties.
3 * To change this template file, choose Tools | Templates
4 * and open the template in the editor.
5 */
6 package client;
7
8 import java.awt.event.KeyEvent;
9 import java.io.DataInputStream;
10 import java.io.DataOutputStream;
11 import java.io.IOException;
12 import java.net.InetAddress;
13 import java.net.Socket;
14 import java.net.UnknownHostException;
39
15 import java.util.logging.Level;
16 import java.util.logging.Logger;
17
18 /**
19 *
20 * @author yamaramin
21 */
22 public class NewJFrame extends javax.swing.JFrame {
23
24 /**
25 * Creates new form NewJFrame
26 */
27 public NewJFrame() {
28 initComponents();
29 }
30
31 /**
32 * This method is called from within the constructor to initialize the form.
33 * WARNING: Do NOT modify this code. The content of this method is always
34 * regenerated by the Form Editor.
35 */
36 @SuppressWarnings("unchecked")
37 // <editor-fold defaultstate="collapsed" desc="Generated Code">
38 private void initComponents() {
39
40 jScrollPane1 = new javax.swing.JScrollPane();
41 jTextArea1 = new javax.swing.JTextArea();
42 jTextField1 = new javax.swing.JTextField();
43 jButton1 = new javax.swing.JButton();
44 jButton2 = new javax.swing.JButton();
45
46 setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
47
48 jTextArea1.setColumns(20);
49 jTextArea1.setRows(5);
50 jScrollPane1.setViewportView(jTextArea1);
51
52 jTextField1.addKeyListener(new java.awt.event.KeyAdapter() {
53 public void keyPressed(java.awt.event.KeyEvent evt) {
54 jTextField1KeyPressed(evt);
55 }
56 });
57
58 jButton1.setText("Send");
59 jButton1.addActionListener(new java.awt.event.ActionListener() {
60 public void actionPerformed(java.awt.event.ActionEvent evt) {
61 jButton1ActionPerformed(evt);
62 }
63 });
64
65 jButton2.setText("Connect");
66 jButton2.addActionListener(new java.awt.event.ActionListener() {
67 public void actionPerformed(java.awt.event.ActionEvent evt) {
68 jButton2ActionPerformed(evt);
69 }
40
70 });
71
72 javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
73 getContentPane().setLayout(layout);
74 layout.setHorizontalGroup(
75 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
76 .addComponent(jScrollPane1)
77 .addGroup(layout.createSequentialGroup()
78 .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, 329,
javax.swing.GroupLayout.PREFERRED_SIZE)
79 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED,
javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
80 .addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, 81,
javax.swing.GroupLayout.PREFERRED_SIZE))
81 .addGroup(layout.createSequentialGroup()
82 .addContainerGap()
83 .addComponent(jButton2)
84 .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
85 );
86 layout.setVerticalGroup(
87 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
88 .addGroup(layout.createSequentialGroup()
89 .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 214,
javax.swing.GroupLayout.PREFERRED_SIZE)
90 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
91 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
92 .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE,
javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
93 .addComponent(jButton1))
94 .addGap(18, 18, 18)
95 .addComponent(jButton2)
96 .addGap(0, 16, Short.MAX_VALUE))
97 );
98
99 pack();
100 }// </editor-fold>
101 static Socket conn;
102 private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
103 try {
104 conn=new Socket(InetAddress.getLocalHost(), 6000);
105 jTextArea1.setText(InetAddress.getLocalHost().toString());
106 new Thread(){
107 @Override
108 public void run() {
109 while (true) {
110 try {
111 DataInputStream dis=new DataInputStream(conn.getInputStream());
112 String data=dis.readUTF();
113 jTextArea1.setText(jTextArea1.getText()+'\n'+"Server: "+data);
114 } catch (IOException ex) {
115 jTextArea1.setText(jTextArea1.getText()+'\n'+"Send failed! Network error. Exiting...");
116 try {
117 Thread.sleep(3000);
118 System.exit(0);
119 } catch (InterruptedException ex1) {
41
120 Logger.getLogger(NewJFrame.class.getName()).log(Level.SEVERE, null, ex1);
121 }
122 Logger.getLogger(NewJFrame.class.getName()).log(Level.SEVERE, null, ex);
123 }
124 }
125 }
126
127 }.start();
128 } catch (UnknownHostException ex) {
129 Logger.getLogger(NewJFrame.class.getName()).log(Level.SEVERE, null, ex);
130 } catch (IOException ex) {
131 Logger.getLogger(NewJFrame.class.getName()).log(Level.SEVERE, null, ex);
132 }
133
134 }
135
136 private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
137 if(jTextField1.getText()!=""){
138 jTextArea1.setText(jTextArea1.getText()+'\n'+"Client: "+jTextField1.getText());
139 try {
140 DataOutputStream dos=new DataOutputStream(conn.getOutputStream());
141 dos.writeUTF(jTextField1.getText());
142
143 } catch (IOException ex) {
144 jTextArea1.setText(jTextArea1.getText()+'\n'+"Send failed! Network error. Exiting...");
145 try {
146 Thread.sleep(3000);
147 System.exit(0);
148 } catch (InterruptedException ex1) {
149 Logger.getLogger(NewJFrame.class.getName()).log(Level.SEVERE, null, ex1);
150 }
151 Logger.getLogger(NewJFrame.class.getName()).log(Level.SEVERE, null, ex);
152 }
153 jTextField1.setText("");
154
155 }
156 }
157
158 private void jTextField1KeyPressed(java.awt.event.KeyEvent evt) {
159 if(evt.getKeyCode()==KeyEvent.VK_ENTER){
160 if(jTextField1.getText()!=""){
161 jTextArea1.setText(jTextArea1.getText()+'\n'+"Client: "+jTextField1.getText());
162 try {
163 DataOutputStream dos=new DataOutputStream(conn.getOutputStream());
164 dos.writeUTF(jTextField1.getText());
165
166 } catch (IOException ex) {
167 jTextArea1.setText(jTextArea1.getText()+'\n'+"Send failed! Network error. Exiting...");
168 try {
169 Thread.sleep(3000);
170 System.exit(0);
171 } catch (InterruptedException ex1) {
172 Logger.getLogger(NewJFrame.class.getName()).log(Level.SEVERE, null, ex1);
173 }
174 Logger.getLogger(NewJFrame.class.getName()).log(Level.SEVERE, null, ex);
42
175 }
176 jTextField1.setText("");
177 }
178 }
179 }
180
181 /**
182 * @param args the command line arguments
183 */
184 public static void main(String args[]) {
185 /* Set the Nimbus look and feel */
186 //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
187 /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
188 * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
189 */
190 try {
191 for (javax.swing.UIManager.LookAndFeelInfo info :
javax.swing.UIManager.getInstalledLookAndFeels()) {
192 if ("Nimbus".equals(info.getName())) {
193 javax.swing.UIManager.setLookAndFeel(info.getClassName());
194 break;
195 }
196 }
197 } catch (ClassNotFoundException ex) {
198 java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE,
null, ex);
199 } catch (InstantiationException ex) {
200 java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE,
null, ex);
201 } catch (IllegalAccessException ex) {
202 java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE,
null, ex);
203 } catch (javax.swing.UnsupportedLookAndFeelException ex) {
204 java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE,
null, ex);
205 }
206 //</editor-fold>
207
208 /* Create and display the form */
209 java.awt.EventQueue.invokeLater(new Runnable() {
210 public void run() {
211 new NewJFrame().setVisible(true);
212 }
213 });
214 }
215
216 // Variables declaration - do not modify
217 private javax.swing.JButton jButton1;
218 private javax.swing.JButton jButton2;
219 private javax.swing.JScrollPane jScrollPane1;
220 private javax.swing.JTextArea jTextArea1;
221 private javax.swing.JTextField jTextField1;
222 // End of variables declaration
223 }
43
Sockets for Servers
The previous lesson discussed sockets from the standpoint of clients: programs that open a
socket to a server that’s listening for connections. However, client sockets themselves aren’t
enough; clients aren’t much use unless they can talk to a server, and the Socket class discussed
in the previous chapter is not sufficient for writing servers. To create a Socket, you need to know
the Internet host to which you want to connect.
When you’re writing a server, you don’t know in advance who will contact you; and even if you
did, you wouldn’t know when that host wanted to contact you. In other words, servers are like
receptionists who sit by the phone and wait for incoming calls. They don’t know who will call or
when, only that when the phone rings, they have to pick it up and talk to whoever is there. You
can’t program that behavior with the Socket class alone.
For servers that accept connections, Java provides a ServerSocket class that represents server
sockets. In essence, a server socket’s job is to sit by the phone and wait for incoming calls. More
technically, a server socket runs on the server and listens for incoming TCP connections. Each
server socket listens on a particular port on the server machine. When a client on a remote host
attempts to connect to that port, the server wakes up, negotiates the connection between the
client and the server, and returns a regular Socket object representing the socket between the
two hosts. In other words, server sockets wait for connections while client sockets initiate
connections. Once a ServerSocket has set up the connection, the server uses a regular Socket
object to send data to the client. Data always travels over the regular socket.
Using ServerSockets
The ServerSocket class contains everything needed to write servers in Java. It has constructors
that create new ServerSocket objects, methods that listen for connections on a specified port,
methods that configure the various server socket options, and the usual miscellaneous methods
such as toString().
In Java, the basic life cycle of a server program is this:
1. A new ServerSocket is created on a particular port using a ServerSocket() constructor.
2. The ServerSocket listens for incoming connection attempts on that port using its
accept() method. accept() blocks until a client attempts to make a connection, at which
point accept() returns a Socket object connecting the client and the server.
3. Depending on the type of server, either the Socket’s getInputStream() method,
getOutputStream() method, or both are called to get input and output streams
that communicate with the client.
44
4. The server and the client interact according to an agreed-upon protocol until it is time
to close the connection.
5. The server, the client, or both close the connection.
6. The server returns to step 2 and waits for the next connection.
1 /*
2 * To change this license header, choose License Headers in Project Properties.
3 * To change this template file, choose Tools | Templates
4 * and open the template in the editor.
5 */
6 package server;
7
8 import java.io.DataInputStream;
9 import java.io.DataOutputStream;
10 import java.io.IOException;
11 import java.net.InetAddress;
12 import java.net.ServerSocket;
13 import java.net.Socket;
14 import java.net.UnknownHostException;
15 import java.util.logging.Level;
16 import java.util.logging.Logger;
17
18 /**
19 *
20 * @author yamaramin
45
21 */
22 public class NewJFrame extends javax.swing.JFrame {
23
24 /**
25 * Creates new form NewJFrame
26 */
27 public NewJFrame() {
28 initComponents();
29 }
30
31 /**
32 * This method is called from within the constructor to initialize the form.
33 * WARNING: Do NOT modify this code. The content of this method is always
34 * regenerated by the Form Editor.
35 */
36 @SuppressWarnings("unchecked")
37 // <editor-fold defaultstate="collapsed" desc="Generated Code">
38 private void initComponents() {
39
40 jScrollPane1 = new javax.swing.JScrollPane();
41 jTextArea1 = new javax.swing.JTextArea();
42 jTextField1 = new javax.swing.JTextField();
43 jButton1 = new javax.swing.JButton();
44 jButton2 = new javax.swing.JButton();
45
46 setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
47
48 jTextArea1.setColumns(20);
49 jTextArea1.setRows(5);
50 jScrollPane1.setViewportView(jTextArea1);
51
52 jButton1.setText("Send");
53 jButton1.addActionListener(new java.awt.event.ActionListener() {
54 public void actionPerformed(java.awt.event.ActionEvent evt) {
55 jButton1ActionPerformed(evt);
56 }
57 });
58
59 jButton2.setText("Start");
60 jButton2.addActionListener(new java.awt.event.ActionListener() {
61 public void actionPerformed(java.awt.event.ActionEvent evt) {
62 jButton2ActionPerformed(evt);
63 }
64 });
65
66 javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
67 getContentPane().setLayout(layout);
68 layout.setHorizontalGroup(
69 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
70 .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 400, Short.MAX_VALUE)
71 .addGroup(layout.createSequentialGroup()
72 .addComponent(jTextField1)
73 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
74 .addComponent(jButton1))
75 .addGroup(layout.createSequentialGroup()
46
76 .addContainerGap()
77 .addComponent(jButton2)
78 .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
79 );
80 layout.setVerticalGroup(
81 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
82 .addGroup(layout.createSequentialGroup()
83 .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 222,
javax.swing.GroupLayout.PREFERRED_SIZE)
84 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
85 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
86 .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE,
javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
87 .addComponent(jButton1))
88 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
89 .addComponent(jButton2)
90 .addGap(0, 15, Short.MAX_VALUE))
91 );
92
93 pack();
94 }// </editor-fold>
95 static ServerSocket ss;
96 static Socket conn;
97 private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
98 try {
99 ss=new ServerSocket(6000, 1, InetAddress.getLocalHost());
100 conn=ss.accept();
101 new Thread(){
102 @Override
103 public void run() {
104 while(true){
105 try {
106 DataInputStream dis=new DataInputStream(conn.getInputStream());
107 String data=dis.readUTF();
108 jTextArea1.setText(jTextArea1.getText()+'\n'+"Client: "+data);
109 } catch (IOException ex) {
110 jTextArea1.setText(jTextArea1.getText()+'\n'+"Send failed! Network error. Exiting...");
111 try {
112 Thread.sleep(3000);
113 System.exit(0);
114 } catch (InterruptedException ex1) {
115 Logger.getLogger(NewJFrame.class.getName()).log(Level.SEVERE, null, ex1);
116 }
117 Logger.getLogger(NewJFrame.class.getName()).log(Level.SEVERE, null, ex);
118 }
119 }
120 }
121 }.start();
122 } catch (UnknownHostException ex) {
123 Logger.getLogger(NewJFrame.class.getName()).log(Level.SEVERE, null, ex);
124 } catch (IOException ex) {
125 Logger.getLogger(NewJFrame.class.getName()).log(Level.SEVERE, null, ex);
126 }
127
128 }
47
129
130 private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
131 if(jTextField1.getText()!=""){
132 jTextArea1.setText(jTextArea1.getText()+'\n'+"Server: "+jTextField1.getText());
133 try {
134 DataOutputStream dos=new DataOutputStream(conn.getOutputStream());
135 dos.writeUTF(jTextField1.getText());
136 } catch (IOException ex) {
137 jTextArea1.setText(jTextArea1.getText()+'\n'+"Send failed! Network error. Exiting...");
138 try {
139 Thread.sleep(3000);
140 System.exit(0);
141 } catch (InterruptedException ex1) {
142 Logger.getLogger(NewJFrame.class.getName()).log(Level.SEVERE, null, ex1);
143 }
144 Logger.getLogger(NewJFrame.class.getName()).log(Level.SEVERE, null, ex);
145 }
146 jTextField1.setText("");
147
148 }
149 }
150
151 /**
152 * @param args the command line arguments
153 */
154 public static void main(String args[]) {
155 /* Set the Nimbus look and feel */
156 //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
157 /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
158 * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
159 */
160 try {
161 for (javax.swing.UIManager.LookAndFeelInfo info :
javax.swing.UIManager.getInstalledLookAndFeels()) {
162 if ("Nimbus".equals(info.getName())) {
163 javax.swing.UIManager.setLookAndFeel(info.getClassName());
164 break;
165 }
166 }
167 } catch (ClassNotFoundException ex) {
168 java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE,
null, ex);
169 } catch (InstantiationException ex) {
170 java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE,
null, ex);
171 } catch (IllegalAccessException ex) {
172 java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE,
null, ex);
173 } catch (javax.swing.UnsupportedLookAndFeelException ex) {
174 java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE,
null, ex);
175 }
176 //</editor-fold>
177
178 /* Create and display the form */
48
179 java.awt.EventQueue.invokeLater(new Runnable() {
180 public void run() {
181 new NewJFrame().setVisible(true);
182 }
183 });
184 }
185
186 // Variables declaration - do not modify
187 private javax.swing.JButton jButton1;
188 private javax.swing.JButton jButton2;
189 private javax.swing.JScrollPane jScrollPane1;
190 private javax.swing.JTextArea jTextArea1;
191 private javax.swing.JTextField jTextField1;
192 // End of variables declaration
193 }
49