java服务器c 客户端程序_求一个java用客户端和服务器程序实现C/S模式下的通信,还要实现多线程的聊天室代码...

展开全部

客户端:

import java.awt.BorderLayout;

import java.awt.Color;

import java.awt.GridLayout;

import java.awt.Toolkit;

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.InputStreamReader;

import java.io.PrintWriter;

import java.net.Socket;

import java.util.HashMap;

import java.util.Map;

import java.util.StringTokenizer;

import javax.swing.DefaultListModel;

import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JLabel;

import javax.swing.JList;

import javax.swing.JOptionPane;

import javax.swing.JPanel;

import javax.swing.JScrollPane;

import javax.swing.JSplitPane;

import javax.swing.JTextArea;

import javax.swing.JTextField;

import javax.swing.border.TitledBorder;

public class Client{

private JFrame frame;

private JList userList;

private JTextArea textArea;

private JTextField textField;

private JTextField txt_port;

private JTextField txt_hostIp;

private JTextField txt_name;

private JButton btn_start;

private JButton btn_stop;

private JButton btn_send;

private JPanel northPanel;

private JPanel southPanel;

private JScrollPane rightScroll;

private JScrollPane leftScroll;

private JSplitPane centerSplit;

private DefaultListModel listModel;

private boolean isConnected = false;

private Socket socket;

private PrintWriter writer;

private BufferedReader reader;

private MessageThread messageThread;// 负责接收消息的62616964757a686964616fe78988e69d8331333330343263线程

private Map onLineUsers = new HashMap();// 所有在线用户

// 主方法,程序入口

public static void main(String[] args) {

new Client();

}

// 执行发送

public void send() {

if (!isConnected) {

JOptionPane.showMessageDialog(frame, "还没有连接服务器,无法发送消息!", "错误",

JOptionPane.ERROR_MESSAGE);

return;

}

String message = textField.getText().trim();

if (message == null || message.equals("")) {

JOptionPane.showMessageDialog(frame, "消息不能为空!", "错误",

JOptionPane.ERROR_MESSAGE);

return;

}

sendMessage(frame.getTitle() + "@" + "ALL" + "@" + message);

textField.setText(null);

}

// 构造方法

public Client() {

textArea = new JTextArea();

textArea.setEditable(false);

textArea.setForeground(Color.blue);

textField = new JTextField();

txt_port = new JTextField("719");

txt_hostIp = new JTextField("127.0.0.1");

txt_name = new JTextField("Lei");

btn_start = new JButton("连接");

btn_stop = new JButton("断开");

btn_send = new JButton("发送");

listModel = new DefaultListModel();

userList = new JList(listModel);

northPanel = new JPanel();

northPanel.setLayout(new GridLayout(1, 7));

northPanel.add(new JLabel("端口"));

northPanel.add(txt_port);

northPanel.add(new JLabel("服务器IP"));

northPanel.add(txt_hostIp);

northPanel.add(new JLabel("姓名"));

northPanel.add(txt_name);

northPanel.add(btn_start);

northPanel.add(btn_stop);

northPanel.setBorder(new TitledBorder("连接信息"));

rightScroll = new JScrollPane(textArea);

rightScroll.setBorder(new TitledBorder("消息显示区"));

leftScroll = new JScrollPane(userList);

leftScroll.setBorder(new TitledBorder("在线用户"));

southPanel = new JPanel(new BorderLayout());

southPanel.add(textField, "Center");

southPanel.add(btn_send, "East");

southPanel.setBorder(new TitledBorder("写消息"));

centerSplit = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, leftScroll,

rightScroll);

centerSplit.setDividerLocation(100);

frame = new JFrame("客户机");

// 更改JFrame的图标:

//frame.setIconImage(Toolkit.getDefaultToolkit().createImage(Client.class.getResource("qq.png")));

frame.setLayout(new BorderLayout());

frame.add(northPanel, "North");

frame.add(centerSplit, "Center");

frame.add(southPanel, "South");

frame.setSize(600, 400);

int screen_width = Toolkit.getDefaultToolkit().getScreenSize().width;

int screen_height = Toolkit.getDefaultToolkit().getScreenSize().height;

frame.setLocation((screen_width - frame.getWidth()) / 2,

(screen_height - frame.getHeight()) / 2);

frame.setVisible(true);

// 写消息的文本框中按回车键时事件

textField.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent arg0) {

send();

}

});

// 单击发送按钮时事件

btn_send.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) {

send();

}

});

// 单击连接按钮时事件

btn_start.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) {

int port;

if (isConnected) {

JOptionPane.showMessageDialog(frame, "已处于连接上状态,不要重复连接!",

"错误", JOptionPane.ERROR_MESSAGE);

return;

}

try {

try {

port = Integer.parseInt(txt_port.getText().trim());

} catch (NumberFormatException e2) {

throw new Exception("端口号不符合要求!端口为整数!");

}

String hostIp = txt_hostIp.getText().trim();

String name = txt_name.getText().trim();

if (name.equals("") || hostIp.equals("")) {

throw new Exception("姓名、服务器IP不能为空!");

}

boolean flag = connectServer(port, hostIp, name);

if (flag == false) {

throw new Exception("与服务器连接失败!");

}

frame.setTitle(name);

JOptionPane.showMessageDialog(frame, "成功连接!");

} catch (Exception exc) {

JOptionPane.showMessageDialog(frame, exc.getMessage(),

"错误", JOptionPane.ERROR_MESSAGE);

}

}

});

// 单击断开按钮时事件

btn_stop.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) {

if (!isConnected) {

JOptionPane.showMessageDialog(frame, "已处于断开状态,不要重复断开!",

"错误", JOptionPane.ERROR_MESSAGE);

return;

}

try {

boolean flag = closeConnection();// 断开连接

if (flag == false) {

throw new Exception("断开连接发生异常!");

}

JOptionPane.showMessageDialog(frame, "成功断开!");

} catch (Exception exc) {

JOptionPane.showMessageDialog(frame, exc.getMessage(),

"错误", JOptionPane.ERROR_MESSAGE);

}

}

});

// 关闭窗口时事件

frame.addWindowListener(new WindowAdapter() {

public void windowClosing(WindowEvent e) {

if (isConnected) {

closeConnection();// 关闭连接

}

System.exit(0);// 退出程序

}

});

}

/**

* 连接服务器

*

* @param port

* @param hostIp

* @param name

*/

public boolean connectServer(int port, String hostIp, String name) {

// 连接服务器

try {

socket = new Socket(hostIp, port);// 根据端口号和服务器ip建立连接

writer = new PrintWriter(socket.getOutputStream());

reader = new BufferedReader(new InputStreamReader(socket

.getInputStream()));

// 发送客户端用户基本信息(用户名和ip地址)

sendMessage(name + "@" + socket.getLocalAddress().toString());

// 开启接收消息的线程

messageThread = new MessageThread(reader, textArea);

messageThread.start();

isConnected = true;// 已经连接上了

return true;

} catch (Exception e) {

textArea.append("与端口号为:" + port + " IP地址为:" + hostIp

+ " 的服务器连接失败!" + "\r\n");

isConnected = false;// 未连接上

return false;

}

}

/**

* 发送消息

*

* @param message

*/

public void sendMessage(String message) {

writer.println(message);

writer.flush();

}

/**

* 客户端主动关闭连接

*/

@SuppressWarnings("deprecation")

public synchronized boolean closeConnection() {

try {

sendMessage("CLOSE");// 发送断开连接命令给服务器

messageThread.stop();// 停止接受消息线程

// 释放资源

if (reader != null) {

reader.close();

}

if (writer != null) {

writer.close();

}

if (socket != null) {

socket.close();

}

isConnected = false;

return true;

} catch (IOException e1) {

e1.printStackTrace();

isConnected = true;

return false;

}

}

// 不断接收消息的线程

class MessageThread extends Thread {

private BufferedReader reader;

private JTextArea textArea;

// 接收消息线程的构造方法

public MessageThread(BufferedReader reader, JTextArea textArea) {

this.reader = reader;

this.textArea = textArea;

}

// 被动的关闭连接

public synchronized void closeCon() throws Exception {

// 清空用户列表

listModel.removeAllElements();

// 被动的关闭连接释放资源

if (reader != null) {

reader.close();

}

if (writer != null) {

writer.close();

}

if (socket != null) {

socket.close();

}

isConnected = false;// 修改状态为断开

}

public void run() {

String message = "";

while (true) {

try {

message = reader.readLine();

StringTokenizer stringTokenizer = new StringTokenizer(

message, "/@");

String command = stringTokenizer.nextToken();// 命令

if (command.equals("CLOSE"))// 服务器已关闭命令

{

textArea.append("服务器已关闭!\r\n");

closeCon();// 被动的关闭连接

return;// 结束线程

} else if (command.equals("ADD")) {// 有用户上线更新在线列表

String username = "";

String userIp = "";

if ((username = stringTokenizer.nextToken()) != null

&& (userIp = stringTokenizer.nextToken()) != null) {

User user = new User(username, userIp);

onLineUsers.put(username, user);

listModel.addElement(username);

}

} else if (command.equals("DELETE")) {// 有用户下线更新在线列表

String username = stringTokenizer.nextToken();

User user = (User) onLineUsers.get(username);

onLineUsers.remove(user);

listModel.removeElement(username);

} else if (command.equals("USERLIST")) {// 加载在线用户列表

int size = Integer

.parseInt(stringTokenizer.nextToken());

String username = null;

String userIp = null;

for (int i = 0; i < size; i++) {

username = stringTokenizer.nextToken();

userIp = stringTokenizer.nextToken();

User user = new User(username, userIp);

onLineUsers.put(username, user);

listModel.addElement(username);

}

} else if (command.equals("MAX")) {// 人数已达上限

textArea.append(stringTokenizer.nextToken()

+ stringTokenizer.nextToken() + "\r\n");

closeCon();// 被动的关闭连接

JOptionPane.showMessageDialog(frame, "服务器缓冲区已满!", "错误",

JOptionPane.ERROR_MESSAGE);

return;// 结束线程

} else {// 普通消息

textArea.append(message + "\r\n");

}

} catch (IOException e) {

e.printStackTrace();

} catch (Exception e) {

e.printStackTrace();

}

}

}

}

}

更多追问追答

追问

非常感谢,没有服务器的吗??

追答

有啊 但不了 回答限制了字数

追问

那可以把不够的在回答中补上吗?

追答

只能输入1000个字,贴不了 - -+

追问

能发一下邮箱吗?345006229@qq.com,非常感谢!会给你追加的。。

追答

OK

本回答由电脑网络分类达人 董辉推荐

2Q==

c50d6af2748da18e06a2dc6d9597acd0.gif

已赞过

已踩过<

你对这个回答的评价是?

评论

收起

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值