简单socket 聊天室 C/S模式 小例子

一个简单的使用socket 的简单的 S/C 模式的聊天程序;

 

周六重新拿以前没弄好的代码改改,弄的;(客户端的程序就不想改了,那时写的太难看了代码)

下面就直接上 运行的截图,图形的东东弄的很粗糙 ,就是几个的面板组件 直接扔上去就没有了,(界面就没什么好看的了)!:

 

按回车来发送消息的,服务端就是原样返回数据  这里会出现名字  是在客户端 发送消息时就加上的;

 

这就是最中间的一段代码,是循环接收客户端请求的;(直接给代码了)

 
public void run() {
try {
// 打开服务器的 指定端口
ServerSocket serverSocket = new ServerSocket(idk);
// 打印信息--->>>>??
// System.out.println("服务器已经创建");
msgArea.append("服务器已经创建\n");

while (true) {
// 接收客户端的请求
Socket socket = serverSocket.accept();
// 添加 接收到的 socket 加到列表里面
if (socketMan.add(socket)) {
// 人数变化
socketMan.sendClientCount();
}
// 开始信息读取 转发 的 线程!
new
}
} catch (Exception e) {
msgArea.append("端口开放错误!!可能是为无效端口!\n");
}
}

(注释什么的有点乱,这是重新那大二写的代码改的,那时候没弄好,线程会卡死)

 

然后是write_Thread(socket).start();

的代码:(接收客户端数据 然后 原样的 用writerAll方法来 发送给所有连上(没连上)的客户端)

 
class write_Thread extends Thread {
Socket socket = null;
BufferedReader reader;
BufferedWriter writer;

public write_Thread(Socket socket) {
this.socket = socket;
}
public void run() {
try {
// 输入流 用来读取接收的数据
reader = new BufferedReader(new InputStreamReader(
socket.getInputStream()));

// writer = new PrintWriter(socket.getOutputStream(), true);

// 输出流 用来 发送接收的数据
writer = new BufferedWriter(new OutputStreamWriter(
socket.getOutputStream()));

String msg;

while ((msg = reader.readLine()) != null) {
System.out.println(msg);
// 显示信息到面板
msgArea.append(msg + "\n");

// 发送到其他所有的 用户
socketMan.writerAll(msg);

}
} catch (Exception e) {
// e.printStackTrace();
msgArea.append("接收数据错误!!\n");
}
}
}

没有什么东东了;后面就直接把源代码贴上来好了:

服务端:

package T802_CS;

import java.net.*;
import java.io.*;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.lang.Runnable;
import java.awt.event.*;
import javax.swing.JButton;
import java.util.*;
import java.io.PrintWriter;
import java.util.ArrayList;
import javax.swing.JFrame;
import T802_CS.Server.SocketManager;


public class Server extends JFrame {

String bjip = this.getip();
int p = 0;
String ip = null;
String dk = null;
int idk = 0;

// *********************************************************************************************
public String getip() {
InetAddress intAddress;
String localip = "1234567890";
try {
intAddress = InetAddress.getLocalHost();
localip = intAddress.getHostAddress();
return localip;
} catch (Exception e) {
e.printStackTrace();
}
return localip;
}

// *********************************************************************************************
public SocketManager socketMan = new SocketManager();
private JPanel jpanel = new JPanel();
// private JTextField sendField =new JTextField();
private JLabel Ftext = new JLabel("欢迎使用,请输入端口后点击启动");
private JLabel bbjj = new JLabel("本机IP:");
private JLabel Dtext = new JLabel("端口(1024~60000):");
private JLabel BJIP = new JLabel(bjip);
private JTextField DKField = new JTextField();

private JScrollPane jScrollPanel = new javax.swing.JScrollPane();
private JTextArea msgArea = new JTextArea(); // 文本域对象

// private BufferedReader reader;
// private PrintWriter writer;
private Socket socket;

Server(String title) {
// 标题的名字
super(title);
// 窗口大小
this.setSize(395, 500);


// 添加面板
this.add(jpanel);
jpanel.setLayout(null); // 个、 窗体布局
// jpanel.add(sendField);
// sendField.setBounds(10,305,320,21);

jScrollPanel.setViewportView(msgArea);
jpanel.add(jScrollPanel);
msgArea.setEditable(false); // msg Area 对象为不可变异状态
msgArea.setColumns(20);
msgArea.setRows(5);

jScrollPanel.setBounds(10, 150, 360, 300);

// 提示信息
jpanel.add(Ftext);
Ftext.setBounds(10, 45, 300, 20);

// 提示信息 本机端口号
jpanel.add(Dtext);
Dtext.setBounds(10, 100, 200, 20);

// 显示 本机的具体IP
jpanel.add(BJIP);
BJIP.setBounds(70, 120, 200, 30);

// 提示信息 本机IP
jpanel.add(bbjj);
bbjj.setBounds(10, 120, 60, 20);

// 输入框 要求输入的端口号
jpanel.add(DKField);
DKField.setBounds(150, 100, 60, 21);

// *********************************************************************************************
// jpanel.add(jScrollPanel);
// jScrollPanel.setBounds(10,80,320,220);
// msgArea.setColumns(20);
// msgArea.setRows(5);
// jScrollPanel.setViewportView(msgArea);
// jpanel.add(jScrollPanel);
// jScrollPanel.setBounds(10,80,320,220);
// *********************************************************************************************

// 启动按钮
final JButton entry = new JButton();
entry.setText("启 动");
entry.setBounds(250, 95, 63, 30);
jpanel.add(entry);

entry.addActionListener(new ActionListener() {
// @Override
public void actionPerformed(ActionEvent e) {

// dk 为端口号 后面为从面板中的端口号输入文本中提取数字
dk = DKField.getText();

// ????????这个是好久以前写的 现在懒得改了!
StringTokenizer st = new StringTokenizer(dk, "*");
// 获取端口 --->>>>为int类型
idk = Integer.parseInt(st.nextToken());

// 创建服务器核心类
ServerProcess server = new ServerProcess();
// 启用核心类里面的启动方法
server.getServer();
}
});

// exit按钮
final JButton entry2 = new JButton();
entry2.setText("EXIT");
entry2.setBounds(250, 55, 63, 30);
jpanel.add(entry2);

entry2.addActionListener(new ActionListener() {
// @Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});

}

// *****************************************************************************************
// *********************************************************************************************

public class SocketManager extends HashSet<Socket> {

public synchronized boolean add(Socket socket) {
return super.add(socket);
}

synchronized void delete(Socket socket) {
super.remove(socket);
}

synchronized void sendClientCount() {
String info = "聊天人数变化,当前为" + size() + "人在线!\n";
System.out.println(info);
msgArea.append(info);
writerAll(info);

}

// ****************************************
// 给所有连接的用户发送消息
void writerAll(String str) {
PrintWriter writer = null;
//Socket cocket;
int n = size();

//发送消息
for (Socket it : this) {
try {

writer = new PrintWriter(it.getOutputStream(), true);
if (writer != null)

writer.println(str);

// System.out.println(str);

// msgArea.append(str + "\n");

} catch (Exception e) {
// e.printStackTrace();
msgArea.append("fasong xiaoxi xichang !!\n");
}
}

}
}
// ****************************************************************************************8
// *******************************************************************************

// 服务器的核心方法!!!!!!!!!

class ServerProcess extends Thread {
// 创建一个 socket 连接的 列表(在线人数)
// public SocketManager socketMan = new SocketManager();



public ServerProcess() {
super();
// TODO Auto-generated constructor stub
}

void getServer() {
this.start();

// 测试是否联通
// new update().start();

}

// 循环接收 客户的 请求

@Override
public void run() {
try {
// 打开服务器的 指定端口
ServerSocket serverSocket = new ServerSocket(idk);

// 打印信息--->>>>??
// System.out.println("服务器已经创建");
msgArea.append("服务器已经创建\n");

while (true) {
// 接收客户端的请求
Socket socket = serverSocket.accept();
// 添加 接收到的 socket 加到列表里面
if (socketMan.add(socket)) {
// 人数变化
socketMan.sendClientCount();
}
// 开始信息读取 转发 的 线程!
new write_Thread(socket).start();

}
} catch (Exception e) {
msgArea.append("端口开放错误!!可能是为无效端口!\n");
}

}
}



// 线程 用来和 客服端 通讯 接收 和 发送 数据

class write_Thread extends Thread {
Socket socket = null;
BufferedReader reader;
BufferedWriter writer;

public write_Thread(Socket socket) {
this.socket = socket;
}

public void run() {
try {
// 输入流 用来读取接收的数据
reader = new BufferedReader(new InputStreamReader(
socket.getInputStream()));

// writer = new PrintWriter(socket.getOutputStream(), true);

// 输出流 用来 发送接收的数据
writer = new BufferedWriter(new OutputStreamWriter(
socket.getOutputStream()));

String msg;

while ((msg = reader.readLine()) != null) {
System.out.println(msg);
// 显示信息到面板
msgArea.append(msg + "\n");

// 发送到其他所有的 用户
socketMan.writerAll(msg);

}
} catch (Exception e) {
// e.printStackTrace();
msgArea.append("接收数据错误!!\n");
}
}
}

// ****************************************************************
// 这个没法用 会出错的样子!!
class update extends Thread {

public void run() {
while (true) {
Iterator<Socket> iterator = socketMan.iterator();
boolean oo = false;
while (iterator.hasNext()) {
Socket ddSocket = iterator.next();
if (ddSocket.isConnected()) {
iterator.remove();
oo = true;
}
}
// 人数变化,发送消息通知!
if (oo)
socketMan.sendClientCount();
// try {
// // 没5秒更新一次
// Thread.sleep(5000);
// } catch (InterruptedException e) {
// // TODO Auto-generated catch block
// // e.printStackTrace();
// }
}

}
}

// *********************************************************************************************

public static void main(String[] args) {

Server client = new Server("小杭聊天器 服务终端");
client.setVisible(true);

}

}

客户端:

(这个就是以前做的,没有改,代码写的很难看。。。。)

对了  这个客户端没有退出  :-(  线程程序会一直执行 。。

package T802_CS;

import java.net.*;
import java.io.*;
//import java.awt.*;
import javax.swing.*;
//import java.awt.BorderLayout;
//import java.awt.EventQueue;
//import java.awt.Event;
import java.awt.event.ActionEvent;
import java.lang.Runnable;
import java.awt.event.*;
import javax.swing.JButton;
import java.util.*;

public class Client extends JFrame /* implements Runnable */{

String bjip = this.getip();
int p = 0;
String ip = null;
String dk = null;
int idk = 0;
private JPanel jpanel = new JPanel();
private JLabel nameLabel = new JLabel("姓名:"); // 标签对象
private JTextField nameField = new JTextField(); // 文本框对象
private JTextArea msgArea = new JTextArea(); // 文本域对象
private JTextField sendField = new JTextField();
private JLabel Ftext = new JLabel("服务器IP:");
private JLabel bbjj = new JLabel("本机IP:");
private JLabel Dtext = new JLabel("端口(1024~60000):");
private JLabel BJIP = new JLabel(bjip);
private JTextField FWField = new JTextField();
private JTextField DKField = new JTextField();
private JScrollPane jScrollPanel = new javax.swing.JScrollPane();
private BufferedReader reader;
private PrintWriter writer;
private Socket socket;

private Client(String title) {
super(title);
this.setSize(360, 425); // 窗口大小
this.add(jpanel);
jpanel.setLayout(null); // 个、 窗体布局
msgArea.setEditable(false); // msg Area 对象为不可变异状态
jpanel.add(nameLabel); // 将标签添加到面板上
nameLabel.setBounds(10, 10, 60, 20); // 设计布局
jpanel.add(nameField);
nameField.setBounds(60, 10, 270, 21);
jpanel.add(sendField);
sendField.setBounds(10, 305, 320, 21);
jpanel.add(Ftext);
Ftext.setBounds(10, 45, 120, 20);
jpanel.add(Dtext);
Dtext.setBounds(10, 335, 200, 20);
jpanel.add(BJIP);
BJIP.setBounds(70, 353, 200, 30);
jpanel.add(bbjj);
bbjj.setBounds(10, 355, 60, 20);

jpanel.add(FWField);
FWField.setBounds(120, 45, 200, 21);
jpanel.add(DKField);
DKField.setBounds(150, 335, 60, 21);
// final JButton entry=new JButton();
// entry.setText("连 接");
// entry.setBounds(230,340,63,30);
// jpanel.add(entry);
msgArea.setColumns(20);
msgArea.setRows(5);
jScrollPanel.setViewportView(msgArea);
jpanel.add(jScrollPanel);
jScrollPanel.setBounds(10, 80, 320, 220);
sendField.addActionListener(new ActionListener() {
// @Override
public void actionPerformed(ActionEvent e) {
writer.println(nameField.getText() + ":" + sendField.getText());

sendField.setText("");
}
});

}

public class supermm implements Runnable {
public void run() {
msgArea.append("聊天准备完毕\n");
gogo();
}

public void gogo() {
String qy = null;
while (true) {
try {
// 在文本域中将读取内容分行显示
qy = null;
// qy=reader.readLine();

while ((qy = reader.readLine()) != null) {
msgArea.append(qy + "\n");
}

} catch (Exception e) {
e.printStackTrace();
}
}
}
}

void getSocket() {
msgArea.append("尝试与服务器连接\n");
try {
socket = new Socket(ip, idk);
reader = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
writer = new PrintWriter(socket.getOutputStream(), true);

// *************************************************************************
Runnable MM = new supermm();
Thread mymm = new Thread(MM);
mymm.start();
// new supermm().start();
// msgArea.append("聊天准备完毕\n");

// *************************************************************************

} catch (Exception e) {
e.printStackTrace();
}

}

public String getip() {
InetAddress intAddress;
String localip = "1234567890";

try {
intAddress = InetAddress.getLocalHost();
localip = intAddress.getHostAddress();
return localip;

} catch (Exception e) {
e.printStackTrace();

}

return localip;

}

public void entryplay() {

final JButton entry = new JButton();
entry.setText("连 接");

entry.setBounds(250, 340, 63, 30);
jpanel.add(entry);

while (p == 0) {
entry.addActionListener(new ActionListener() {
// @Override
public void actionPerformed(ActionEvent e) {
p = 1;
ip = FWField.getText();
dk = DKField.getText();
StringTokenizer st = new StringTokenizer(dk, "*");
idk = Integer.parseInt(st.nextToken());
}
});
}
}

public static void main(String[] args) {

Client client = new Client("小杭聊天器 客户端");
client.setVisible(true);
client.entryplay();
client.getSocket();
}
}

以上的东东,写的很差其实 ,有很多都没有考虑到;技术 时间有限  就不想弄了。目前还在学习中。。。。。。

 

 

 

 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小_杭

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值