`

java socket 编程 登录

阅读更多

给你一个聊天室的,这个是客户端之间的通信,服务器负责接收和转发,你所要的服务器与客户端对发,只要给服务器写个界面显示和输入就行,所有代码如下:
你测试的时候应该把所有代码放在同一个工程下,因为客户端可服务器共用同一个POJO,里面有些包的错误,删除掉就行了
服务器代码,即服务器入口程序:
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectOutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;
import java.util.HashSet;



public class ChatRoomServer {
private ServerSocket ss;
private HashSet<Socket> allSockets;
private UserDao dao;

public  ChatRoomServer(){
  try {
   ss=new ServerSocket(9999);
  
   allSockets=new HashSet<Socket>();
   dao=new UserDaoForTextFile(new File("d:/stu/user.txt"));
  } catch (IOException e) {
   e.printStackTrace();
  }
}

public void startService() throws IOException{
  while(true){
   Socket s=ss.accept();
   allSockets.add(s);
   new ChatRoomServerThread(s).start();
  }
}

class ChatRoomServerThread extends Thread{
  private Socket s;
 
  public ChatRoomServerThread(Socket s){
   this.s=s;
  }
 
  public void run(){
   //1,得到Socket的输入流,并包装。
   //2,循环从输入流中读取一行数据。
   //3,每读到一行数据,判断该行是否是退出命令?
   //4,如果是退出命令,则将当前socket从集合中删除,关闭当前socket,并跳出循环
   //5,如果不是退出命令,则将该消model.getCurrentUser().getName()息转发给所有在线的客户端。
   //   循环遍历allSockets集合,得到每一个socket的输出流,向流中写出该消息。
   BufferedReader br=null;
   String str = null;
   try {
     br = new BufferedReader(new InputStreamReader(s
       .getInputStream()));
    while((str=br.readLine())!=null ){
     if(str.indexOf("%EXIT%")==0){
      allSockets.remove(s);
      //向其他客户端发送XXX退出的消息
      sendMessageToAllClient(str.split(":")[1]+"离开聊天室!");
      s.close();
      break;
     }else if(str.indexOf("%LOGIN%")==0){
      String userName=str.split(":")[1];
      String password=str.split(":")[2];
      User user=dao.getUser(userName, password);
      ObjectOutputStream oos=new ObjectOutputStream(s.getOutputStream());
      oos.writeObject(user);
      oos.flush();
      if(user!=null){
       sendMessageToAllClient(user.getName()+"进入聊天室!");
      }
      str = null;
     }
     if(str!=null){
      sendMessageToAllClient(str);
     }
    }
   } catch (Exception e) {
   
    e.printStackTrace();
   }
  }
 
  public void sendMessageToAllClient(String message)throws IOException{
   Date date=new Date();
   System.out.println(s.getInetAddress()+":"+message+"\t["+date+"]");
   for(Socket temps:allSockets){
    PrintWriter pw=new PrintWriter(temps.getOutputStream());
    pw.println(message+"\t["+date+"]");
    pw.flush();
   }
  
  }
 
}

public static void main(String[] args) {
  try {
   new ChatRoomServer().startService();
  } catch (IOException e) {
   e.printStackTrace();
  }
}

}

客户端代码:
总共4个:
1:入口程序:
public class ChatRoomClient {
private ClientModel model;

public ChatRoomClient(){
//  String hostName = JOptionPane.showInputDialog(null,
//  "请输入服务器主机名:");
//  String portName = JOptionPane
//  .showInputDialog(null, "请输入端口号:");
  //固定服务端IP和端口
  model=new ClientModel("127.0.0.1",Integer.parseInt("9999"));
  model.createSocket();
  new LoginFrame(model).showMe();
}
public static void main(String[] args) {
  new ChatRoomClient();
}
}

2:登陆后显示界面:
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;

public class ClientMainFrame extends JFrame{
private JTextArea area;
private JTextField field;
private JLabel label;
private JButton button;
private ClientModel model;

public ClientMainFrame(){
  super("聊天室客户端v1.0");
  area=new JTextArea(20,40);
  field=new JTextField(25);
  button=new JButton("发送");
  label=new JLabel();
 
  JScrollPane jsp=new JScrollPane(area);
  this.add(jsp,BorderLayout.CENTER);
 
  JPanel panel=new JPanel();
  panel.add(label);
  panel.add(field);
  panel.add(button);
 
  this.add(panel,BorderLayout.SOUTH);
 
  addEventHandler();
}

public ClientMainFrame(ClientModel model){
  this();
  this.model=model;
  label.setText(model.getCurrentUser().getName());
}

public void addEventHandler(){
  ActionListener lis=new SendEventListener();
  button.addActionListener(lis);
  field.addActionListener(lis);
 
  this.addWindowListener(new WindowAdapter(){
   public void windowClosing(WindowEvent arg0) {
   int op=JOptionPane.showConfirmDialog(null,"确认退出聊天室吗?","确认退出",JOptionPane.YES_NO_OPTION);
    if(op==JOptionPane.YES_OPTION){
     PrintWriter pw = model.getOutputStream();
     if(model.getCurrentUser().getName()!=null){
      pw.println("%EXIT%:"+model.getCurrentUser().getName());
      pw.flush();
     }
     try {
      Thread.sleep(200);
     } catch (Exception e) {
     }
     System.exit(0);
    }
   }
  });
}

public void showMe(){
  this.pack();
  this.setVisible(true);
  this.setLocation(300,300);
  this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
  new ReadMessageThread().start();
}

class SendEventListener implements ActionListener{
  public void actionPerformed(ActionEvent e) {
   String str=field.getText().trim();
   if(str.equals("")){
    JOptionPane.showMessageDialog(null, "不能发送空消息!");
    return;
   }
   PrintWriter pw = model.getOutputStream();
   pw.println(model.getCurrentUser().getName()+":"+str);
   pw.flush();
   field.setText("");
  }
}

class ReadMessageThread extends Thread{
  public void run(){
  
   while(true){
    try {
     BufferedReader br = model.getInputStream();
     String str=br.readLine();
     area.append(str+"\n");
    } catch (IOException e) {
   
    }
   }
  }
}
}

3:登陆界面:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.PrintWriter;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;



public class LoginFrame extends JFrame {

private static final long serialVersionUID = 1L;

private JPanel jContentPane = null;

private JLabel lab1 = null;

private JLabel lab2 = null;

private JLabel lab3 = null;

private JTextField userNameField = null;

private JPasswordField passwordField = null;

private JButton loginButton = null;

private JButton registerButton = null;

private JButton cancelButton = null;

private ClientModel model = null;

/**
  * This method initializes userNameField
  * 
  * @return javax.swing.JTextField
  */
private JTextField getUserNameField() {
  if (userNameField == null) {
   userNameField = new JTextField();
   userNameField.setSize(new Dimension(171, 33));
   userNameField.setFont(new Font("Dialog", Font.PLAIN, 18));
   userNameField.setLocation(new Point(140, 70));
  }
  return userNameField;
}

/**
  * This method initializes passwordField
  * 
  * @return javax.swing.JPasswordField
  */
private JPasswordField getPasswordField() {
  if (passwordField == null) {
   passwordField = new JPasswordField();
   passwordField.setSize(new Dimension(173, 30));
   passwordField.setFont(new Font("Dialog", Font.PLAIN, 18));
   passwordField.setLocation(new Point(140, 110));
  }
  return passwordField;
}

/**
  * This method initializes loginButton
  * 
  * @return javax.swing.JButton
  */
private JButton getLoginButton() {
  if (loginButton == null) {
   loginButton = new JButton();
   loginButton.setLocation(new Point(25, 180));
   loginButton.setText("登录");
   loginButton.setSize(new Dimension(75, 30));
  }
  return loginButton;
}


/**
  * This method initializes cancelButton
  * 
  * @return javax.swing.JButton
  */
private JButton getCancelButton() {
  if (cancelButton == null) {
   cancelButton = new JButton();
   cancelButton.setLocation(new Point(270, 180));
   cancelButton.setText("取消");
   cancelButton.setSize(new Dimension(75, 30));
  }
  return cancelButton;
}

/**
  * 显示界面的方法,在该方法中调用addEventHandler()方法给组件添加事件监听器
  *
  */
public  void showMe(){
  this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
  this.setVisible(true);
  this.setLocation(300,200);
  addEventHandler();
}

/**
  * 该方法用于给组件添加事件监听
  *
  */
public void addEventHandler(){
  ActionListener loginListener=new LoginEventListener();
  loginButton.addActionListener(loginListener);
  passwordField.addActionListener(loginListener);


  cancelButton.addActionListener(new ActionListener(){
   public void actionPerformed(ActionEvent e) {
    try {
     model.getSocket().close();
    } catch (IOException e1) {
     e1.printStackTrace();
    }
    System.exit(0);
   }
  });
 
  this.addWindowListener(new WindowAdapter(){
   public void windowClosing(WindowEvent arg0) {
    try {
     model.getSocket().close();
    } catch (IOException e1) {
     e1.printStackTrace();
    }
    System.exit(0);
   }
  });
}

/**
  * 该内部类用来监听登录事件
  * @author Administrator
  *
  */
class LoginEventListener implements ActionListener{
  public void actionPerformed(ActionEvent e) {
   //?????登录的代码
   //1,判断用户名和密码是否为空
   //2,从clientmodel得到输出流,PrintWriter
   //3,发送登录请求给服务器
   //pw.println("%LOGIN%:userName:password");
   //4,从socket得到对象输入流,从流中读取一个对象。
   //5,如果读到的对象为null,则显示登录失败的消息。
   //6,如果读到的对象不为空,则转成User对象,并且将
   // clientModel的currentUser对象设置为该对象。
   //7,并销毁当前窗口,打开主界面窗口。
   String userName = userNameField.getText();
   char[] c = passwordField.getPassword();
   String password = String.valueOf(c);
   if(userName == null || userName.equals("")){
    JOptionPane.showMessageDialog(null,"用户名不能为空");
    return;
   }
   if(password == null || password.equals("")){
    JOptionPane.showMessageDialog(null,"密码名不能为空");
    return;
   }
   PrintWriter pw = model.getOutputStream();
   pw.println("%LOGIN%:"+userName+":"+password);
   pw.flush();
   try {
    InputStream is = model.getSocket().getInputStream();
    System.out.println("is"+is.getClass());
    ObjectInputStream ois = new ObjectInputStream(is);
    Object obj = ois.readObject();
    if(obj != null){
     User user = (User)obj;
     if(user != null){
      model.setCurrentUser(user);
      LoginFrame.this.dispose();
      new ClientMainFrame(model).showMe();
     }
    }
    else{
     JOptionPane.showMessageDialog(null,"用户名或密码错误,请重新输入");
     userNameField.setText("");
     passwordField.setText("");
     return;
    }
   } catch (Exception e1) {
    e1.printStackTrace();
   }
  }
}


public static void main(String[] args) {
  new LoginFrame().showMe();
}

/**
  * This is the default constructor
  */
public LoginFrame(ClientModel model) {
  this();
  this.model=model;
}

public LoginFrame(){
  super();
  initialize();
}

public ClientModel getModel() {
  return model;
}

public void setModel(ClientModel model) {
  this.model = model;
}

/**
  * This method initializes this
  *
  * @return void
  */
private void initialize() {
  this.setSize(362, 267);
  this.setContentPane(getJContentPane());
  this.setTitle("达内聊天室--用户登录");
}

/**
  * This method initializes jContentPane
  *
  * @return javax.swing.JPanel
  */
private JPanel getJContentPane() {
  if (jContentPane == null) {
   lab3 = new JLabel();
   lab3.setText("密    码:");
   lab3.setSize(new Dimension(80, 30));
   lab3.setFont(new Font("Dialog", Font.BOLD, 18));
   lab3.setLocation(new Point(50, 110));
   lab2 = new JLabel();
   lab2.setText("用户名:");
   lab2.setSize(new Dimension(80, 30));
   lab2.setToolTipText("");
   lab2.setFont(new Font("Dialog", Font.BOLD, 18));
   lab2.setLocation(new Point(50, 70));
   lab1 = new JLabel();
   lab1.setBounds(new Rectangle(54, 12, 245, 43));
   lab1.setFont(new Font("Dialog", Font.BOLD, 24));
   lab1.setForeground(new Color(0, 0, 204));
   lab1.setText("聊天室--用户登录");
   jContentPane = new JPanel();
   jContentPane.setLayout(null);
   jContentPane.add(lab1, null);
   jContentPane.add(lab2, null);
   jContentPane.add(lab3, null);
   jContentPane.add(getUserNameField(), null);
   jContentPane.add(getPasswordField(), null);
   jContentPane.add(getLoginButton(), null);
   jContentPane.add(getCancelButton(), null);
  }
  return jContentPane;
}

}

4:客户端管理socket类
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;



/**
* 该类定义客户端的全局参数,如:Socket,当前用户,流对象等
*
*/
public class ClientModel {
private Socket socket;
private User currentUser;
private BufferedReader br;
private PrintWriter pw;
private String hostName;
private int port;

public Socket getSocket() {
  return socket;
}

public ClientModel(String hostName, int port) {
  super();
  this.hostName = hostName;
  this.port = port;
}

public User getCurrentUser() {
  return currentUser;
}

public void setCurrentUser(User currentUser) {
  this.currentUser = currentUser;
}

public synchronized Socket createSocket(){
  if(socket==null){
   try {
    socket=new Socket(hostName,port);
   }catch (IOException e) {
    e.printStackTrace();
    return null;
   }
  }
  return socket;
}

public synchronized BufferedReader getInputStream(){
  if (br==null) {
   try {
    br = new BufferedReader(new InputStreamReader(socket
      .getInputStream()));
   } catch (IOException e) {
    e.printStackTrace();
    return null;
   }
  } 
  return br;
}

public synchronized PrintWriter getOutputStream(){
  if (pw==null) {
   try {
    pw = new PrintWriter(socket.getOutputStream());
   } catch (IOException e) {
    e.printStackTrace();
    return null;
   }
  }
  return pw;
}
public synchronized void closeSocket(){
  if(socket!=null){
   try {
    br.close();
    pw.close();
    socket.close();
   } catch (IOException e) {
    e.printStackTrace();
   }
  }
  socket=null;
  br=null;
  pw=null;
}

}

这里是工具和POJO类:
User类:
import java.io.Serializable;

public class User implements Serializable {
private static final long serialVersionUID = 1986L;
  private int id;
  private String name;
  private String password;
  private String email;
  public User(){}
  public User( String name, String password, String email) {
   super();
   this.name = name;
   this.password = password;
   this.email = email;
  }
  public User( String name, String password) {
   super();
   this.name = name;
   this.password = password;
  }
  public int getId() {
   return id;
  }
  public void setId(int id) {
   this.id = id;
  }
  public String getName() {
   return name;
  }
  public void setName(String name) {
   this.name = name;
  }
  public String getPassword() {
   return password;
  }
  public void setPassword(String password) {
   this.password = password;
  }
  public String getEmail() {
   return email;
  }
  public void setEmail(String email) {
   this.email = email;
  }
 
  public String toString(){
   return id+":"+name+":"+password+":"+email;
  }

}

DAO,用于从本地读取配置文件
接口:


public interface UserDao {
  public boolean addUser(User user);
  public User getUser(String userName,String password);
}
实现类:
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;



public class UserDaoForTextFile implements UserDao{
private File userFile;
public UserDaoForTextFile(){
}
public UserDaoForTextFile(File file){
  this.userFile = file;
  if(!file.exists()){
   try {
    file.createNewFile();
   } catch (IOException e) {
    e.printStackTrace();
   }
  }
}
public synchronized boolean addUser(User user) {
  FileInputStream fis = null;
  BufferedReader br = null;
  int lastId = 0;
  try{
   fis = new FileInputStream(userFile);
   br = new BufferedReader(new InputStreamReader(fis));
   String str = null;
   String lastLine = null;
   while((str=br.readLine()) != null){
    //得到最后一行值
    lastLine = str;
    if(str.split(":")[1].equals(user.getName())){
     return false;
    }
   }
   if(lastLine != null)
   lastId = Integer.parseInt(lastLine.split(":")[0]);
  }catch(Exception e){
   e.printStackTrace();
  }finally{
   if(br!=null)try{br.close();}catch(IOException e){}
   if(fis!=null)try{fis.close();}catch(IOException e){}
  }
 
  FileOutputStream fos = null;
  PrintWriter pw = null;
 
  try{
   fos = new FileOutputStream(userFile,true);
   pw = new PrintWriter(fos);
   user.setId(lastId+1);
   pw.println(user);
   pw.flush();
   return true;
  }catch(Exception e){
   e.printStackTrace();
   }finally{
    if(pw!=null)try{pw.close();}catch(Exception e){}
    if(fos!=null)try{fos.close();}catch(IOException e){}
   }
 
  return false;
}

public synchronized User getUser(String userName, String password) {
  FileInputStream fis = null;
  BufferedReader br = null;
  String str = null;
  User user = null;
 
  try{
   fis = new FileInputStream(userFile);
   br = new BufferedReader(new InputStreamReader(fis));
   while((str = br.readLine()) != null){
    String[] s = str.split(":");
    if(userName.equals(s[1]) && password.equals(s[2])){
     user = new User();
     user.setId(Integer.parseInt(s[0]));
     user.setName(s[1]);
     user.setPassword(s[2]);
     user.setEmail(s[3]);
    }
   }
  }catch(IOException e){
   e.printStackTrace();
  }finally{
   if(br!=null)try{br.close();}catch(IOException e){}
   if(fis!=null)try{fis.close();}catch(IOException e){}
  }
  return user;
}

}

配置文件格式为:
id流水号:用户名:密码:邮箱
1:yawin:034437:yawin@126.com
2:zhoujg:034437:zhou@126.com

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics