Buscamos urgentemente un sistema de chat en Java
//Cliente de sala de chat
importar java.applet.*;
importar java.awt.*
importar java. io.*;
importar java.net.*;
importar java.awt.event.*
clase pública ChatClient extiende Applet{
protected boolean loggedIn; //Estado de inicio de sesión
Marco protegido cp; //Marco de la sala de chat
protegido static int PORTNUM=7777 //Número de puerto predeterminado 7777 ; p>
protected int port; //Número de puerto real
sock de socket protegido
bufferedReader protegido es //BufferedReader utilizado para leer datos del calcetín
PrintWriter protegido pw; //PrintWriter usado para escribir datos en sock
TextField protegido tf; //TextField usado para entrada
TextArea protegida ta ;
Botón protegido lib; //Botón de inicio de sesión
Botón protegido lob; //Botón de cerrar sesión
final static String TITLE="Chatroom appletgt;gt;gt; gt;gt;gt;gt;gt;gt;gt;gt;gt;gt;gt;gt;gt;gt;gt;gt;gt;gt;gt;gt;gt ;gt;";
protected String paintMessage; //Mensaje publicado
public ChatParameter Chat;
public void init(){
paintMessage="Generando ventana de chat" ; p>
repintar();
cp=new Frame(TITLE);
cp.setLayout(new BorderLayout ()); =getParameter("port");//Este parámetro no debe ser demasiado claro
port=PORTNUM
if (portNum !=null) //El libro dice portNum== null, lo cual es muy problemático
port=Integer.parseInt(portNum);
//CGI
ta=new TextArea(14, 80); /p>
ta.setEditable(false); //atributo de solo lectura
ta.setFont(new Font("Monospaced",Font.PLAIN ,11)); >cp.add(BorderLayout.NORTE, ta)
Panel p=new Panel();
Botón b;
//para el botón de inicio de sesión
p.add(lib). =nuevo botón("Iniciar sesión"));
lib.setEnabled(true);
lib.requestFocus();
lib.addActionListener(nuevo ActionListener); () {
acción vacía públicaPerformed(ActionEvent e){
login();
lib.setEnabled(false); lob.setEnabled(true);
tf.requestFocus(); //Bloquea la entrada del teclado en el cuadro de texto de la derecha
}
}) ;
//para el botón de cerrar sesión
p.add(lob=new Button ("Cerrar sesión");
lob.setEnabled(false); /p>
p>
lob.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
logout();
lib.setEnabled (verdadero);
lob.setEnabled(falso);
lib.requestFocus()
}
<; p>});p.add(new Label ("Mensaje de entrada: "));
tf=new TextField(40); .addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
if(loggedIn){
//pw.println(Chat. CMD_BCAST tf.getText() ); //Chat.CMD....¿es natural?
int j=tf.getText().indexOf(:");
if(jgt; 0) pw.println(Chat.CMD_MESG tf.getText());
else
pw.println(Chat.CMD_BCAST tf.getText());
tf.setText(""); //¿No usar flux()?
}
}
});
p.add(tf);
cp.add(BorderLayout.SOUTH, p
cp.addWindowListener(nuevo WindowAdapter()); {
public void windowClosing(WindowEvent e){
//Si se ejecuta setVisible o dispose, cierre la ventana
ChatClient.this.cp.setVisible(false);
ChatClient.this.cp.dispose()
cerrar sesión
;}
});
cp.pack();//¿No entiendes para qué se utiliza?
//¿Poner marco? cp en el medio
Dimensión us=cp.getSize(),
them=Toolkit.getDefaultToolkit().getScreenSize();
int newX=( ellos.ancho- nosotros.ancho)/2;
int newY=(ellos.height-us.height)/2
cp.setLocation(newX, newY); /p>
cp.setVisible(true);
paintMessage="La ventana ahora debería estar visible"
repaint()
}
//Inicie sesión en la sala de chat
public void login(){
if(loggedIn) return
try{
sock =new Socket(getCodeBase().getHost(), puerto
es=new BufferedReader(new InputStreamReader(sock.getInputStream())); p>pw=new PrintWriter( sock.getOutputStream(), true);
}catch(IOException e){
showStatus("No se puede obtener el socket: " e);
cp.add(new Label("No se puede obtener el socket: " e));
return;}
// Construir e iniciar el lector. para leer datos del servidor, enviarlos al cuadro de texto
//Aquí, crezca en un hilo para evitar bloquear recursos (bloqueos)
new Thread (new Runnable(){
public void run(){
Línea de cadena
try{
while(loggedIn amp;amp;((line=is .readLine()) !=null))
ta.appendText(line "\n"
}catch(IOException e){
showStatus; ("Dios mío ¡¡¡Ah, desconectado!!!!");
regresar
}
}
}). start( );
//Asumir inicio de sesión (en realidad solo imprime información relevante, no inicio de sesión real)
// pw.println(Chat.CMD_LOGIN "AppletUser"); >
pw.println(Chat.CMD_LOGIN "UsuarioApplet")
;
loggedIn =true;
}
//Imitar código de salida
public void logout(){
if(!loggedIn)
return;
loggedIn=false;
intenta{
if(sock!=null )
sock.close();
}catch(IOException ign){
//Manejo de excepciones
}
}
p>
}
//No hay forma de detenerlo, incluso al saltar del navegador a otra página web
//El programa de chat puede continuar ejecutándose
public void paint(Graphics g){
Dimension d=getSize();
int h=d; .height;
int w= d.ancho;
g.fillRect(0, 0, w, 2);
g.setColor(Color. negro);
g.drawString (paintMessage, 10, (h/2)-5
}
}
); Lado del servidor de la sala de chat
importar java .net.*
importar java.io.*
importar java.util.*;
ChatServer de clase pública{
//ID del administrador de la sala de chat
Cadena estática final protegida CHATMASTER_ID="ChatMaster"
//Delimitador de información del sistema;
Cadena estática final protegida SEP=": ";
//Socket del servidor
ServSock ServerSocket protegido
//Cliente actual; lista
clientes ArrayList protegidos
//indicadores de depuración
depuración booleana protegida=false
chat público ChatParameter
//Construcción del método principal Un ChatServer, sin valor de retorno
public static void main(String[] argv){
System.out.println("Chat server0. 1 iniciogt;gt;gt; gt; gt; gt; gt; gt; gt;
w .runServer();
System.out.println("***ERROR*** Chat server0.1 saliendo"); }
/ /Construir y ejecutar un servicio de chat
ChatServer(){
Chat=
new ChatParameter();
clients=new ArrayList();
try{
servSock=new ServerSocket(7777); Pero puede ser que él mismo haya definido una clase
System.out.println("Chat Server0.1 escuchando en el puerto:"
}catch(Exception e) {
log("Excepción de IO en ChatServer.lt;initgt;");
System.exit(0); p >}
public void runServer(){
intenta{
mientras(verdadero){
Socket us=servSock.accept ( );
String hostName=us.getInetAddress().getHostName();
System.out.println("Aceptado desde " hostName); //Un hilo de procesamiento
ChatHandler cl=new ChatHandler(us, hostName
synchronized(clients){
clients.add(cl); /p>
cl.start();
if(clients.size()==1)
cl.send(CHATMASTER_ID, "¡Bienvenido! Eres el primero uno aquí");
else{
cl.send(CHATMASTER_ID, "¡Bienvenido! Eres el último de los usuarios de"
clients.size() " .");
}
}
}
}catch(Excepción e){
log ("Excepción de IO en runServer:" e);
System.exit(0
}
}
void protegido); log(String s){
System.out.println(s);
}
//Clase interna que maneja sesiones
clase protegida ChatHandler extiende Thread {
//Socket de cliente
Socket protegido clientSock
//BufferedReader que lee el socket
BufferedReader protegido es
//PrintWriter que envía líneas de información en el socket
PrintWriter pw protegido
//Cliente fuera del host
<; p>protegtedString clientIP
//Handle
inicio de sesión de cadena protegida
ChatHandler público (Socket sock, String clnt) lanza IOException {
clientSock=calcetín;
clientIP=clnt;
is=new BufferedReader(
new InputStreamReader(sock.getInputStream())); p>pw=new PrintWriter (sock.getOutputStream(), true);
}
//Cada ChatHandler es un hilo y el siguiente es su método run()
p>//Se utiliza para procesar sesiones
public void run(){
Línea de cadena
try{
while((line=is.readLine())!=null){
char c=line.charAt(0);
line=line.substring(1); /p>
switch(c){
//case Chat.CMD_LOGIN:
case 'l':
if(!Chat. isValidLoginName (línea)){
send(CHATMASTER_ID, "INICIAR SESIÓN" línea "no válida");
log("INICIAR SESIÓN NO VÁLIDA desde: " clientIP); continuar;
}
login=line;
broadcast(CHATMASTER_ID, iniciar sesión "se une a nosotros, para un total de"
clientes. .size() " usuarios");
romper;
// caso Chat.CMD_MESG:
caso 'm':
if(login==null){
send(CHATMASTER_ID, "inicie sesión primero");
continuar
}
< p; >int donde =line.indexOf(Chat.SEPARATOR);String recip=line.substring(0, donde
String mesg=line.substring (donde 1);
log("MESG: " iniciar sesión "---gt; " recip ": " mesg
ChatHandler cl=lookup(recip); if(cl==null)
psend(CHATMASTER_ID, recip "no ha iniciado sesión."
else
cl.psend(iniciar sesión, mesg ) ;
brea
k;
//case Chat.CMD_QUIT:
case 'q':
broadcast(CHATMASTER_ID, "Adiós a " iniciar sesión "@" clientIP);
close();
return; //ChatHandler finaliza
// caso Chat.CMD_BCAST:
caso 'b':
if(iniciar sesión!=null)
broadcast(iniciar sesión, línea
else
log("Blt; L FROM); " clientIP);
romper;
predeterminado:
log("Desconocer cmd" c "from" login "@" clientIP);
}
}
}catch(IOException e){
log("IO Excepción: " e); }finalmente{
//Se acabó el calcetín, terminamos
//Aún no puedo enviar un mensaje de despedida
//Debe haber un simple protocolo basado en comandos Eso es todo
System.out.println(login SEP "All Done");
synchronized(clients){
clients.remove( this);
if(clients.size()==0){
System.out.println(CHATMASTER_ID SEP
"Estoy tan solo Podría llorar; gt; gt; gt; gt; ");
}else if(clients.size()==1){
ChatHandler last=(ChatHandler)clientes. .get(0 );
last.send(CHATMASTER_ID, "Oye, estás hablando contigo mismo otra vez"); p>
broadcast(CHATMASTER_ID, "Ahora hay" client.size() "usuarios"
}
}
} p>
}
protected void close(){
if(clientSock==null){
log("cerrar cuando no esté abierto")
regresar
}
intenta{
clientSock.close()
clientSock=null; ;
}catch(IOException e){
log("Error durante el cierre de " clientIP); /p>
//Enviar mensaje al usuario
voi público
d send(String sender, String mesg){
pw.println(sender SEP "*gt;" mesg);
}
//Enviar privado; Mensaje
protegido void psend(String sender, String msg){
send("lt;*" sender "*gt;", msg); }
//Enviar un mensaje a todos los usuarios
difusión pública vacía (String sender, String mesg){
System.out.println(" Broadcasting" remitente SEP mesg);
for(int i=0; ilt; client.size(); i ){
ChatHandler sib=(ChatHandler)clients.get(i);
if(DEBUG)
System.out.println("Enviando a" sib
sib.send(remitente, mensaje
}
if(DEBUG) System.out.println("Transmisión terminada");
}
búsqueda de ChatHandler protegida (nick de cadena) {
sincronizado(clientes){
for(int i=0; ilt; clientes.size(); i ){
ChatHandler cl= (ChatHandler )clientes.get(i);
if(cl.login.equals(nick))
return cl
}
}
return null;
}
//Convierte el objeto ChatHandler en una cadena
public String toString(){
return "ChatHandler[" login "]"
}
}
}
ChatParameter de clase pública; {
carácter final estático público CMD_BCAST='b';
carácter final estático público CMD_LOGIN='l'
carácter final estático público CMD_MESG ='m; ';
carácter final estático público CMD_QUIT='q';
carácter final estático público SEPARATOR=':';//? PORTNUM=7777;
público booleano isValidLoginName(línea de cadena){
if (línea.e)
quals("CHATMASTER_ID"))
devuelve falso
devuelve verdadero;
}
public void main(String[] argv ){
}
}
El código anterior puede estar un poco desordenado debido a limitaciones de la interfaz. Simplemente cópielo, reorganícelo y modifíquelo. p >