2019独角兽企业重金招聘Python工程师标准>>>
package com.socketForm;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.io.IOError;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Scanner;
import javax.swing.DefaultListModel;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextArea;
import javax.swing.KeyStroke;
import javax.swing.ListModel;
import javax.swing.border.TitledBorder;
/**
* 聊天程序服务器窗口
* @author dingzhen
* @version 2016-03-09
*/
public class ServerForm extends JFrame{
private static final long serialVersionUID = 1L;
private static final int PORT = 9090; //端口号
private JTextArea area; //用户放用户信息的显示区
private DefaultListModel lm; //列表对像,用户保存用户登录信息
private Map<String,Object> usersMap = new HashMap<String, Object>(); //保存所有在线用户的名称和Socket
public ServerForm() throws Exception{
area = new JTextArea();
area.setEditable(false);
lm = new DefaultListModel();
getContentPane().add(new JScrollPane(area));
JList list= new JList(lm);
JScrollPane jc = new JScrollPane(list);
jc.setPreferredSize(new Dimension(100,this.getHeight()));
jc.setBorder(new TitledBorder("在线"));
getContentPane().add(jc,BorderLayout.EAST);
JMenuBar bar = new JMenuBar(); //声明一组菜单
JMenu m = new JMenu("控制");
bar.add(m);
m.setMnemonic('C');
final JMenuItem run = new JMenuItem("开启");
run.setAccelerator(KeyStroke.getKeyStroke('R',KeyEvent.CTRL_MASK)); //设置快捷键
run.setActionCommand("run");
m.add(run);
m.addSeparator();
JMenuItem exit = new JMenuItem("退出");
exit.setAccelerator(KeyStroke.getKeyStroke('E',KeyEvent.CTRL_MASK));
exit.setActionCommand("exit");
m.add(exit);
setJMenuBar(bar);
ActionListener al = new ActionListener(){ //添加一个内部类,以启动服务器
public void actionPerformed(ActionEvent e) {
if(e.getActionCommand().equals("run")){
startServer();
run.setEnabled(false);
}else{
System.exit(0);
}
}
};
run.addActionListener(al);
exit.addActionListener(al);
final int winWidth = 500;
final int winHeight = 400;
Toolkit toolkit = Toolkit.getDefaultToolkit();
int width = (int)toolkit.getScreenSize().getWidth();
int height = (int)toolkit.getScreenSize().getHeight();
setTitle("这是服务器");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(width/2-winWidth/2,height/2-winHeight/2,winWidth, winHeight); //在屏幕的中间显示
setVisible(true);
}
public static void main(String[] args) throws Exception {
JFrame.setDefaultLookAndFeelDecorated(true);
new ServerForm();
}
/**
* 启动服务器
*/
public void startServer(){
try{
System.err.println("启动服务...");
ServerSocket server = new ServerSocket(PORT);
area.append("启动服务:"+server);
new ServerThread(server).start();
}catch(Exception e){
e.printStackTrace();
}
}
/**
* 启动服务的线程
*/
class ServerThread extends Thread{
private ServerSocket server;
public ServerThread(ServerSocket server) {
this.server = server;
}
public void run() {
try{
while(true){
Socket socketClient = server.accept(); //等待获取客户端的连接
Scanner sc = new Scanner(socketClient.getInputStream()); //获取用户端输入流
if(sc.hasNextLine()){
String userName = sc.nextLine();
area.append("\r\n用户:["+userName+"]登录,"+socketClient);
lm.addElement(userName);
new ClientThread(socketClient); //启动这个线程
msgAll(userName); //通知所有人有人登录
msgSelf(socketClient); //通知当前登录的人,有多少人在线
usersMap.put(userName,socketClient);
System.err.println("一个线程已经启动....");
}
}
}catch(Exception e){
e.printStackTrace();
}
}
}
/**
* 服务器开始客户端的线程
*/
class ClientThread extends Thread{
private Socket client;
public ClientThread(Socket client) {
System.err.println("初始。。。。。");
this.client = client;
start();
}
public void run(){
System.err.println("一个线程启动成功。。。。");
try{
Scanner sc = new Scanner(client.getInputStream());
while(sc.hasNextLine()){ //这儿接收用户的信息,格式如下:命令@#给谁@#消息@#自己
String msg = sc.nextLine();
System.err.println(msg);
String[] msgs = msg.split("@#");
if(msgs[0].equals("exit")){ //结束此线程的运行,停止会话
System.err.println("退出人:"+msgs[3]); //还要通知甩有人有人退出,并删除所有人列表中的自己
usersMap.remove(msgs[3]); //从列表中删除此用户的信息
lm.removeElement(msgs[3]); //从服务器的显示列中删除
area.append("\r\n用户["+msgs[3]+"]退出了。");
sendExitMsgToAll(msgs);
break;
}else{
sendMsgToSb(msgs); //发消息给某人
}
}
}catch(Exception e){
e.printStackTrace();
}
}
}
/**
* 通知所有人,有人登录
* 写出信息的类型为:
* 类型:通知(cmd)|消息(msg)@#谁的通知SomeBody@#消息文本MSG
*/
private void msgAll(String userName){
try{
Iterator<Object> it = usersMap.values().iterator();
while(it.hasNext()){
Socket s = (Socket)it.next();
try{
PrintWriter pw = new PrintWriter(s.getOutputStream(),true);
String msg = "msg@#server@#用户["+userName+"]登录了.";
pw.println(msg);
pw.flush();
msg = "cmdAdd@#server@#"+userName;
pw.println(msg);
pw.flush();
}catch(IOException e){
e.printStackTrace();
}
}
}catch(Exception e){
e.printStackTrace();
}
}
/**
* 通知当前登录的人有多少人在线
*/
private void msgSelf(Socket client){
try{
PrintWriter pw = new PrintWriter(client.getOutputStream(),true);
Iterator<String> it = usersMap.keySet().iterator();
while(it.hasNext()){
String msg = "cmdAdd@#server@#"+it.next();
pw.println(msg);
}
}catch(IOException e){
e.printStackTrace();
}
}
/**
* 发消息给某人
*/
private void sendMsgToSb(String[] msgs) throws IOException{
if(msgs[1].equals("全部")){ //发消息给所有人
Iterator<String> userNames = usersMap.keySet().iterator();
while(userNames.hasNext()){
String userName = userNames.next();
if(!userName.equals(msgs[3])){ //如果不是自己
Socket s = (Socket)usersMap.get(userName);
PrintWriter pw = new PrintWriter(s.getOutputStream(),true);
String str = "msg@#"+msgs[3]+"@#"+msgs[2];
pw.println(str);
pw.flush();
}
}
}else{
Socket s = (Socket)usersMap.get(msgs[1]);
PrintWriter pw = new PrintWriter(s.getOutputStream(),true);
String str = "msg@#"+msgs[3]+"@#"+msgs[2];
pw.println(str);
pw.flush();
}
}
/**
* 通知所有人有人退出
*/
private void sendExitMsgToAll(String[] msgs) throws IOException{
Iterator<String> userNames = usersMap.keySet().iterator();
while(userNames.hasNext()){
String userName = userNames.next();
Socket s = (Socket)usersMap.get(userName);
PrintWriter pw = new PrintWriter(s.getOutputStream(),true);
String str = "msg@#server@#用户["+msgs[3]+"]退出了。";
pw.println(str);
pw.flush();
str = "cmdRed@#server@#"+msgs[3];
pw.println(str);
pw.flush();
}
}
}
package com.socketForm;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
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.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.border.LineBorder;
import javax.swing.border.TitledBorder;
/**
* 客户端程序
* @author dingzhen
* @version 2016-03-09
*/
public class ClientForm extends JFrame implements ActionListener{
private static final long serialVersionUID = 1L;
private static String HOST = "127.0.0.1"; //服务器地址
private static int PORT = 9090; //端口号
private JTextField userName; //启用标识
private DefaultListModel lm; //在线用户列表
private JList list;
private JTextField msg; //发消息框
private JTextArea allMsg = new JTextArea(); //收消息框
public ClientForm() throws Exception {
addJMenuBar(); //设置菜单
userName = new JTextField(10);
JPanel p= new JPanel();
p.add(new JLabel("用户标识:"));
p.add(userName);
JButton conn = new JButton("连接");
conn.setActionCommand("c");
conn.addActionListener(this);
p.add(conn);
JButton exitBtn = new JButton("退出");
exitBtn.setActionCommand("exit");
exitBtn.addActionListener(this);
p.add(exitBtn);
p.setBorder(new LineBorder(Color.GRAY));
//以下是中间的面板
JPanel center = new JPanel(new BorderLayout());
lm = new DefaultListModel();
list = new JList(lm);
lm.addElement("全部");
list.setSelectedIndex(0); //默认选中全部
list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
list.setVisibleRowCount(2);
JScrollPane jc = new JScrollPane(list);
jc.setBorder(new TitledBorder("在线"));
jc.setPreferredSize(new Dimension(70,center.getHeight()));
center.add(jc,BorderLayout.EAST);
JPanel send = new JPanel();
send.add(new JLabel("消息:"));
msg = new JTextField(20);
send.add(msg);
JButton sendBtn = new JButton("发送");
sendBtn.setActionCommand("send");
sendBtn.addActionListener(this);
send.add(sendBtn);
center.add(send,BorderLayout.SOUTH);
allMsg.setEditable(false);
center.add(new JScrollPane(allMsg));
Container c = getContentPane();
c.add(p,BorderLayout.NORTH);
c.add(center,BorderLayout.CENTER);
addWindowListener(new WindowAdapter() { //当用户退出时,先要通知所有人,有人退出
public void windowClosing(WindowEvent arg0) {
sendExitMsg();
}
});
setBounds(300, 300, 400, 300);
setVisible(true);
}
public static void main(String[] args) throws Exception {
JFrame.setDefaultLookAndFeelDecorated(true);
new ClientForm();
}
public void actionPerformed(ActionEvent e) {
if(e.getActionCommand().equals("c")){
System.err.println("连接...");
connecting();
}else if(e.getActionCommand().equals("send")){
String msg = "on@#"+list.getSelectedValue()+"@#"+this.msg.getText()+"@#"+userName.getText();
System.err.println(">发出的消息为:"+msg);
pw.println(msg);
pw.flush();
}else if(e.getActionCommand().equals("exit")){ //用户要退出
sendExitMsg();
}
}
/**
* 发送退出的消息
*/
private void sendExitMsg(){
if(client==null){
System.exit(0);
return;
}
String msg = "exit@#全部@#null@#"+userName.getText();
System.err.println("退出:"+msg);
pw.println(msg);
pw.flush();
System.exit(0);
}
/**
* 创建一个用户连接
*/
private Socket client; //声明一个客户端的连接
private PrintWriter pw;
private void connecting(){
try{
System.err.println(HOST+","+PORT);
client= new Socket(HOST,PORT);
String userName = this.userName.getText(); //获取用户标识
pw = new PrintWriter(client.getOutputStream(),true);
pw.println(userName);
this.setTitle("用户["+userName+"]在线...");
new ClientThread().start();
}catch(Exception e){
e.printStackTrace();
}
}
/**
* 用以下线程来读取服务器发送来的信息
*/
class ClientThread extends Thread{
public void run() {
try{
Scanner sc = new Scanner(client.getInputStream());
while(sc.hasNextLine()){
String str = sc.nextLine();
System.err.println("客户端接收到的消息 :"+str);
String[] msg = str.split("@#");
if(msg[0].equals("msg")){ //开头不是msg就是cmd命令
if(msg[1].equals("server")){
str = "[通知]:"+msg[2];
}else{
str = "["+msg[1]+"]说:"+msg[2];
}
allMsg.append("\r\n"+str);
}else if(msg[0].equals("cmdAdd")){ //说明有人登录
lm.addElement(msg[2]);
}else if(msg[0].equals("cmdRed")){ //说明有人退出
lm.removeElement(msg[2]);
}
}
}catch(IOException e){
e.printStackTrace();
}
}
}
/**
* 添加菜单,控制选项,可以设置服务器及端口号
*/
private void addJMenuBar(){
JMenuBar bar = new JMenuBar();
JMenu m = new JMenu("选项");
JMenuItem mi = new JMenuItem("设置");
JMenuItem help = new JMenuItem("帮助");
mi.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
final JDialog set = new JDialog(ClientForm.this,true);
set.setBounds(ClientForm.this.getX(),ClientForm.this.getY(), 300, 100);
set.setLayout(new FlowLayout());
JButton btn = new JButton("设置");
final JTextField host = new JTextField(10);
host.setText("127.0.0.1");
final JTextField port = new JTextField(5);
port.setText("9090");
btn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
ClientForm.HOST = host.getText();
ClientForm.PORT = Integer.parseInt(port.getText());
System.err.println(ClientForm.HOST);
set.dispose(); //关闭且销毁
}
});
set.add(new JLabel("服务器:"));
set.add(host);
set.add(new JLabel(":"));
set.add(port);
set.add(btn);
set.setVisible(true);
}
});
help.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JDialog set = new JDialog(ClientForm.this,true);
set.setBounds(ClientForm.this.getX(),ClientForm.this.getY(), 300, 100);
JLabel jl = new JLabel("版权所有@dingzhen 2016-03-09");
set.add(jl);
set.setVisible(true);
}
});
bar.add(m);
m.add(mi);
m.add(help);
this.setJMenuBar(bar);
}
}