public class QuotePushServer extends Thread
class ClientHandler extends Thread
1:
2: import java.io.*;
3: import java.util.*;
4: import java.net.*;
5:
6: /*
7: Protocol --- Ticker client pull
8:
9: Port: 8002
10:
11: Client: connect
12: Client: WATCH name1 name2 ...
13: Server: name1 quote1 // send all quotes the first time
14: name2 quote2
15: ...
16: Server: DONE
17: Server: name quote // resend quote when changed
18: Server: name quote
19: ...
20: Client: CLOSE
21:
22: Server design:
23: Main thread: waiting for new clients
24: Quote update thread: periodically update quote
25: Client threads: one per client, send quote updates to the clients
26: */
27:
28: public class QuotePushServer extends Thread {
29:
30: static protected String symbol[] = { "IBM", "Sun", "Intel", "Apple", "Compaq" };
31: static protected int quote[] = { 100, 100, 100, 100, 100 };
32: static protected int n = 5;
33: static protected Vector clients = new Vector();
34:
35: public static void main(String[] args) {
36: System.out.println("QuotePullServer started.");
37:
38: new QuotePushServer().start();
39:
40: try {
41: ServerSocket s = new ServerSocket(8002);
42: // Waiting for new clients
43: for (;;) {
44: Socket incoming = s.accept();
45: ClientHandler newClient = new ClientHandler(incoming);
46: clients.addElement(newClient);
47: newClient.start();
48: }
49: } catch (Exception e) {
50: System.err.println(e);
51: }
52:
53: System.out.println("QuotePullServer stopped.");
54: }
55:
56: static public int getQuote(String name) {
57: for (int i = 0; i < n; i++) {
58: if (symbol[i].equals(name)) {
59: return quote[i];
60: }
61: }
62: return 0;
63: }
64:
65: // update quote
66: public void run() {
67: while (true) {
68: try {
69: Thread.currentThread().sleep(10000);
70: System.out.println("New quote:");
71: for (int i = 0; i < n; i++) {
72: int dq = 0;
73: if (Math.random() < 0.5) {
74: dq = (int) ((Math.random() - 0.4) * ( 10.0 * Math.random()));
75: }
76: if (dq > 0) {
77: quote[i] += dq;
78: System.out.println("Changed: " + symbol[i] + " " + quote[i]);
79: Enumeration enum = clients.elements();
80: while (enum.hasMoreElements()) {
81: ClientHandler t = (ClientHandler) enum.nextElement();
82: t.updateQuote(symbol[i], quote[i]);
83: }
84: }
85: }
86: System.out.println("End quote.");
87: } catch (Exception e) {
88: System.err.println(e);
89: }
90: }
91: }
92:
93: }
94:
95: class ClientHandler extends Thread {
96:
97: protected PrintWriter out;
98: protected BufferedReader in;
99: protected Socket socket;
100: protected String symbol[];
101: protected int n;
102:
103:
104: public ClientHandler (Socket socket) {
105: this.socket = socket;
106: try {
107: out = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
108: in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
109: } catch (IOException e) {
110: System.err.println(e);
111: }
112: }
113:
114: public void updateQuote(String name, int quote) {
115: boolean needToSend = false;
116: int i;
117: if (symbol != null) {
118: for (i = 0; i < n; i++) {
119: if (symbol[i].equals(name)) {
120: needToSend = true;
121: break;
122: }
123: }
124: } else {
125: needToSend = true;
126: }
127: if (needToSend) {
128: out.println(name + " " + quote);
129: out.flush();
130: }
131: }
132:
133: public void run() {
134: try {
135: String line;
136: while ((line = in.readLine()) != null) {
137: System.out.println("Receive: " + line);
138: if (line.startsWith("WATCH")) {
139: StringTokenizer tk = new StringTokenizer(line);
140: tk.nextToken();
141: Vector v = new Vector();
142: while (tk.hasMoreTokens()) {
143: v.addElement(tk.nextToken());
144: }
145: n = v.size();
146: symbol = new String[n];
147: int i;
148: for (i = 0; i < n; i++) {
149: symbol[i] = (String) v.elementAt(i);
150: }
151: for (i = 0; i < n; i++) {
152: out.println(symbol[i] + " " +
153: QuotePushServer.getQuote(symbol[i]));
154: }
155: out.println("DONE");
156: out.flush();
157: } else if (line.trim().equals("CLOSE")) {
158: break;
159: }
160: }
161: socket.close();
162: in.close();
163: out.close();
164: } catch (IOException e) {
165: System.err.println(e);
166: }
167: QuotePushServer.clients.removeElement(this);
168: }
169:
170: }