Source code: com/ciphermod/cipherchat/ChatClient.java
1 /* $Id: ChatClient.java,v 1.1 2001/03/26 10:48:43 cvsbob Exp $ */
2
3 /*
4 * ChatClient.java, handles client side of the CipherChat protocol.
5 * Copyright (C) 2001 Robert Bushman.
6 *
7 * I reserve the right to release this program under seperate license.
8 * If you require a special license grant contact Robert Bushman.
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
23 * 02111-1307, USA.
24 */
25
26 package com.ciphermod.cipherchat;
27
28 import java.io.BufferedInputStream;
29 import java.io.DataInputStream;
30 import java.io.DataOutputStream;
31 import java.io.EOFException;
32 import java.io.InputStream;
33 import java.io.IOException;
34 import java.io.OutputStream;
35
36 import java.util.Vector;
37
38 import com.ciphercore.Client;
39
40 public class ChatClient {
41
42 // ----------------------------------------------------------
43 // CONSTANTS
44 // -----------------------------------------------------------
45
46 public static final String
47 CHILD_CLASS_NAME = "com.ciphermod.cipherchat.ChatChild";
48
49 // --------------------------------------------------------------
50 // CONSTRUCTORS
51 // --------------------------------------------------------------
52
53 public ChatClient( String userName, String hostName, int port ) {
54 Client client = new Client( CHILD_CLASS_NAME,
55 hostName,
56 port );
57 setClient( client );
58 setUserName( userName );
59 }
60
61 // -----------------------------------------------------------
62 // PUBLIC API
63 // -----------------------------------------------------------
64
65 public void initialize() {
66 try {
67 getClient().connect();
68 DataInputStream in = new DataInputStream( getBaseInputStream() );
69 DataOutputStream out = new DataOutputStream(getBaseOutputStream());
70 ChatClientReceiver receiver = new ChatClientReceiver( in );
71 setIn( in );
72 setOut( out );
73 setReceiver( receiver );
74 getReceiver().start();
75 getOut().writeInt( getUserName().getBytes().length );
76 getOut().write( getUserName().getBytes() );
77 } catch( IOException e ) {
78 e.printStackTrace();
79 }
80 }
81
82 public void sendMessage( String message ) {
83 try {
84 getOut().writeInt( message.getBytes().length );
85 getOut().write( message.getBytes() );
86 } catch( IOException e ) {
87 e.printStackTrace();
88 }
89 }
90
91 public void close() {
92 try {
93 // This does nothing, the receiver is blocked on getIn().readInt().
94 // When the server closes the conneciton it'll die.
95 getReceiver().pleaseStop();
96 getOut().writeInt( ChatInterface.QUIT );
97 getReceiver().join();
98 getClient().close();
99 } catch( Exception e ) {
100 e.printStackTrace();
101 }
102 }
103
104 // -----------------------------------------------------------
105 // INSTANCE PARAMETERS AND ACCESSORS
106 // -----------------------------------------------------------
107
108 // PARAMETERS
109 private String _userName;
110 private ChatClientReceiver _receiver;
111 private DataInputStream _in;
112 private DataOutputStream _out;
113 private Client _client;
114
115 // SETTERS
116 protected void setUserName( String userName ) { _userName = userName; }
117 protected void setReceiver( ChatClientReceiver receiver ) {
118 _receiver = receiver;
119 }
120 protected void setIn( DataInputStream in ) { _in = in; }
121 protected void setOut( DataOutputStream out ) { _out = out; }
122 protected void setClient( Client client ) { _client = client; }
123
124 // GETTERS
125 public String getUserName() { return( _userName ); }
126 protected ChatClientReceiver getReceiver() { return( _receiver ); }
127 protected DataInputStream getIn() { return( _in ); }
128 protected DataOutputStream getOut() { return( _out ); }
129 protected Client getClient() { return( _client ); }
130
131 // CONVENIENCE GETTERS
132 protected InputStream getBaseInputStream() {
133 return( getClient().getBaseInputStream() );
134 }
135 protected OutputStream getBaseOutputStream() {
136 return( getClient().getBaseOutputStream() );
137 }
138 protected Object[] getMessages() {
139 return( getReceiver().getMessages() );
140 }
141 }
142
143 class ChatClientReceiver extends Thread {
144
145 // -----------------------------------------------------------
146 // CONSTRUCTORS
147 // -----------------------------------------------------------
148
149 public ChatClientReceiver( DataInputStream in ) {
150 setIn( in );
151 }
152
153 // ---------------------------------------------------------
154 // THREAD IMPLEMENTATION
155 // ----------------------------------------------------------
156
157 private boolean _stopRequested = false;
158
159 public void run() {
160 try {
161 Object waiter = new Object();
162 byte[] signalByte = new byte[1];
163 while( ! _stopRequested ) {
164 int messageLength = getIn().readInt();
165 byte[] bytes = new byte[ messageLength ];
166 getIn().readFully( bytes );
167 addMessage( new String( bytes ) );
168 }
169 } catch( EOFException e ) {
170 System.out.println( "Server closed connection."
171 + " Shutting down receiver." );
172 } catch( IOException e ) {
173 e.printStackTrace();
174 }
175 }
176
177 public void pleaseStop() {
178 _stopRequested = true;
179 }
180
181 // ------------------------------------------------------
182 // PUBLIC API
183 // -----------------------------------------------------
184
185 public Object[] getMessages() {
186 Object[] newMessages = new String[0];
187 synchronized( getMessageModToken() ) {
188 newMessages = getMessageBuffer().toArray( newMessages );
189 clearMessages();
190 }
191 return( newMessages );
192 }
193
194 // -----------------------------------------------------
195 // INSTANCE PARAMETERS AND ACCESSORS
196 // ----------------------------------------------------
197
198 // PARAMETERS
199 private Vector _messageBuffer = new Vector();
200 private Object _messageModToken = new Object();
201 private DataInputStream _in;
202
203 // SETTERS
204 protected void addMessage( String message ) {
205 synchronized( getMessageModToken() ) {
206 _messageBuffer.add( message );
207 }
208 }
209 protected void clearMessages() { _messageBuffer.clear(); }
210 protected void setIn( DataInputStream in ) { _in = in; }
211
212 // GETTERS
213 protected Object getMessageModToken() { return( _messageModToken ); }
214 protected DataInputStream getIn() { return( _in ); }
215 protected Vector getMessageBuffer() { return( _messageBuffer ); }
216 }