Problema com sockets

gente estou tentando fazer um chat simples entre duas pessoas… Porém, apenas um esta conseguindo falar com o outro… Está uma ¨$$%#@ mesmo, inclusive a lógica… mas vamos lá… do jeito que está é isto que acontece:
Pessoa 1 = servidor
Pessoa 2 = cliente

  1. A pessoa1 que vai receber a conexão, executa o Servidor.java
  2. A pessoa2 que vai estabelecer a conexão, executa a JanelaPrincipal.java, coloca o IP que o servidor está clica em Configurar
  3. pessoa1: Aparecerá uma msg “conexão estabelecida” (JOptionPane)
  4. pessoa1: Aparecerá uma janela do tipo “JanelaPrincipal” no computador da pessoa…
  5. O que a pessoa2 (cliente) digitar, vai aparecer no que a pessoa1 Servidor digitar

se fosse para as duas conversarem, ambas teriam que executar o Servidor…
ai teriam duas janelas iguais… isso, SE nao tivesse dando erro, pois fiz o teste, e quando a pessoa clica pra configurar da um erro e o programa trava… entao ta feia a coisa

ai vai o servidor…

import java.io.*;
import java.net.*;
import javax.swing.JOptionPane;
//import java.net.ServerSocket;
//import java.net.Socket;


public class Servidor {
        ServerSocket socket;
        Socket acc;
        JanelaPrincipal jan = new JanelaPrincipal();;

    public static void main (String args[]) throws IOException, Exception{
        Servidor server = new Servidor();
        server.receber();
    }

    public Servidor() throws IOException, Exception {
         socket = new ServerSocket(9999);
         acc = socket.accept();
         JOptionPane.showMessageDialog(null, "Conexão estabelecida");
         jan.setVisible(true);

    }


   //loop infinito ... receber chama receber no final da execução.. sei que isso n ta certo! hehe

    public void receber() throws IOException{
            BufferedReader leitor = new BufferedReader(new InputStreamReader(acc.getInputStream()));
            String oi = leitor.readLine();

            String ant = jan.campoHist.getText();
            jan.campoHist.setText(ant+"\nAmigo: "+oi);
            receber();
    }


}

ai vai o cliente:

[code]import java.net.Socket;
import java.io.*;

public class Cliente {

private String mensagem;
PrintStream print;

public void setMensagem(String oi){
    this.mensagem = oi;
}

public void Escrever(){
     print.println(mensagem);
}


public void run(String IP) throws Exception{

    Socket conec = new Socket(IP,9999);
    print = new PrintStream(conec.getOutputStream());

}

}
[/code]

e finalmente a GUI:

import java.util.logging.Level;
import java.util.logging.Logger;

public class JanelaPrincipal extends javax.swing.JFrame {

    Cliente cli;
    Servidor server;
    public JanelaPrincipal() throws Exception {
        super("Chat - Cliente");
        initComponents();
      
        cli = new Cliente();
     
    }


    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        jLabel1 = new javax.swing.JLabel();
        jPanel2 = new javax.swing.JPanel();
        jScrollPane1 = new javax.swing.JScrollPane();
        campo_enviar_msg = new javax.swing.JTextArea();
        botao_enviar = new javax.swing.JButton();
        jPanel3 = new javax.swing.JPanel();
        jLabel2 = new javax.swing.JLabel();
        campoIP = new javax.swing.JTextField();
        botaoConfig = new javax.swing.JButton();
        jPanel1 = new javax.swing.JPanel();
        campo_Hist = new javax.swing.JScrollPane();
        campoHist = new javax.swing.JTextArea();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);

        jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder("Mensagem"));

        campo_enviar_msg.setColumns(20);
        campo_enviar_msg.setRows(5);
        jScrollPane1.setViewportView(campo_enviar_msg);

        botao_enviar.setText("Enviar");
        botao_enviar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                botao_enviarActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
        jPanel2.setLayout(jPanel2Layout);
        jPanel2Layout.setHorizontalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanel2Layout.createSequentialGroup()
                        .addGap(131, 131, 131)
                        .addComponent(botao_enviar, javax.swing.GroupLayout.PREFERRED_SIZE, 178, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 460, Short.MAX_VALUE)))
                .addContainerGap())
        );
        jPanel2Layout.setVerticalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup()
                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 31, Short.MAX_VALUE)
                .addComponent(botao_enviar)
                .addContainerGap())
        );

        jPanel3.setBorder(javax.swing.BorderFactory.createTitledBorder("Configurar"));

        jLabel2.setText("IP do servidor:");

        botaoConfig.setText("Configurar");
        botaoConfig.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                botaoConfigActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3);
        jPanel3.setLayout(jPanel3Layout);
        jPanel3Layout.setHorizontalGroup(
            jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel3Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                    .addComponent(botaoConfig, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addGroup(javax.swing.GroupLayout.Alignment.LEADING, jPanel3Layout.createSequentialGroup()
                        .addComponent(jLabel2)
                        .addGap(18, 18, 18)
                        .addComponent(campoIP, javax.swing.GroupLayout.PREFERRED_SIZE, 351, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addContainerGap(26, Short.MAX_VALUE))
        );
        jPanel3Layout.setVerticalGroup(
            jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel3Layout.createSequentialGroup()
                .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel2)
                    .addComponent(campoIP, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(18, 18, 18)
                .addComponent(botaoConfig)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("Mensagens Trocadas"));

        campo_Hist.setEnabled(false);

        campoHist.setColumns(20);
        campoHist.setFont(new java.awt.Font("Monospaced", 1, 13)); // NOI18N
        campoHist.setRows(5);
        campoHist.setEnabled(false);
        campo_Hist.setViewportView(campoHist);

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(campo_Hist, javax.swing.GroupLayout.DEFAULT_SIZE, 460, Short.MAX_VALUE)
                .addContainerGap())
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addComponent(campo_Hist, javax.swing.GroupLayout.DEFAULT_SIZE, 216, Short.MAX_VALUE)
                .addContainerGap())
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jLabel1))
                    .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addGap(34, 34, 34)
                        .addComponent(jLabel1))
                    .addGroup(layout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(jPanel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addGap(18, 18, 18)
                .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addGap(18, 18, 18)
                .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );

        pack();
    }// </editor-fold>                        

    private void botao_enviarActionPerformed(java.awt.event.ActionEvent evt) {                                             
        // TODO add your handling code here:
        cli.setMensagem(campo_enviar_msg.getText());
        cli.Escrever();

        String oi = campo_enviar_msg.getText();

        String ant = campoHist.getText();
        campoHist.setText(ant + "\nVocê: " + oi);
    }                                            

    private void botaoConfigActionPerformed(java.awt.event.ActionEvent evt) {                                            
        try {
          cli.run(campoIP.getText());
        } catch (Exception ex) {
            Logger.getLogger(JanelaPrincipal.class.getName()).log(Level.SEVERE, null, ex);
        }
    }                                           

    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    new JanelaPrincipal().setVisible(true);
                } catch (Exception ex) {
                    Logger.getLogger(JanelaPrincipal.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        });
    }

    // Variables declaration - do not modify                     
    private javax.swing.JButton botaoConfig;
    private javax.swing.JButton botao_enviar;
    public javax.swing.JTextArea campoHist;
    private javax.swing.JTextField campoIP;
    private javax.swing.JScrollPane campo_Hist;
    private javax.swing.JTextArea campo_enviar_msg;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JScrollPane jScrollPane1;
    // End of variables declaration                   

}

é um projeto do netbeans, quem quiser pegar direto pode baixar:

http://dl.dropbox.com/u/15625458/Socket.rar

Bom… o que fazer para melhorar isso ai? =x
desculpem qqer coisa!
abrazz

esse loop do receber vai ter que rodar em uma thread separada, pois o cara que for o servidor só vai receber as mensagens não vai conseguir responder nunca, a thread dele ta sempre ocupada.

Eu acredito que eu até conseguiria fazer ele responder ali… pois eu tinha feito antes… mas nao ia ficar bom nao =x
pior é q n sei nda de threads e ja foi um custo conseguir o que eu consegui em sockets, pq tb n sei nda1 uhsadhuasdhu

mas ta bom…
vlw ai