在公司没聊天工具,为了方便与同事即时联系,写了此程序。
已有很多注释,就不做多解释了。
Main.java
/**
* 主入口
* @author xKF24276 ruilin.xie
*
*/
public class Main {
//程序主入口
public static void main(String[] args)
{
//实例服务端
Services s = new Services();
//设置服务端监听端口
s.open(88);
//开始监听
s.start();
}
}
Services.java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
/**
* 服务
*
* @author xKF24276 ruilin.xie
*
*/
public class Services extends Thread
{
// 用于存放所有用户的集合
public static List<UserInfo> allUser = new ArrayList<UserInfo>();
// 服务器开启端口
private int port = 80;
// 设置服务器监听端口
public void open(int port)
{
this.port = port;
}
// 主线程,用于监听用户上线
public void run()
{
System.out.println("聊天室服务端启动成功,正在监听用户登录信息...");
// 服务端
ServerSocket srvSocket = null;
// 客户端套接字
Socket client = null;
// 客户端输出流
OutputStream out = null;
// 客户端输入流
InputStream in = null;
// 用户名字
String yourname = null;
try
{
// 打开服务
srvSocket = new ServerSocket(port);
} catch (IOException e) {
e.printStackTrace();
}
while (true)
{
try
{
// 休眠0.5s
Thread.sleep(500);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
try
{
// 等待客户机登录
client = srvSocket.accept();
out = client.getOutputStream();
// 发送欢迎信息
OutputStreamWriter writer = new OutputStreamWriter(out);
writer.write("\t\tWelcome ! \r\nInput YourName : ");
writer.flush();
// 获取用户输入用户名
in = client.getInputStream();
InputStreamReader inreader = new InputStreamReader(in);
BufferedReader reader = new BufferedReader(inreader);
yourname = reader.readLine();
// 初始化用户信息
UserInfo uinfo = new UserInfo();
uinfo.setClient(client);
uinfo.setUip(client.getInetAddress().getHostAddress());
if (yourname != null)
{
yourname = checkYourName(yourname);
uinfo.setUname(yourname);
// 用户存入集合
allUser.add(uinfo);
System.out.println("〖系统消息:" + yourname + " 上线 !〗");
// 发送提示登录成功
writer.write("〖系统消息: Login Success, OnLine Count : "
+ allUser.size() + "〗\r\n");
writer.flush();
// 启动该用户监听线程
SrvBuss sb = new SrvBuss();
// 设置用户信息
sb.setUserInfo(uinfo);
sb.start();
// 向其他用户提示有用户上线
sb.sendAllMsg("〖系统消息: " + yourname + " 上线 !〗\r\n");
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
// 用户如果存在,那么给新用户新标识
public String checkYourName(String uname)
{
for (int i = 0; i < allUser.size(); i++)
{
UserInfo uinfo = allUser.get(i);
if (uinfo.getUname().equals(uname.trim()))
{
return uname + "_" + StrUtil.NumStr(5);
}
}
return uname;
}
}
SrvBuss.java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
/**
* 单用户线程处理
*
* @author xKF24276 ruilin.xie
*
*/
public class SrvBuss extends Thread
{
// 登录用户信息
private UserInfo uinfo = null;
public void setUserInfo(UserInfo uinfo)
{
this.uinfo = uinfo;
}
public UserInfo getUserInfo()
{
return this.uinfo;
}
// 副线程,用于单用户监听
public void run()
{
// 得到单用户信息
Socket client = uinfo.getClient();
String line = null;
while (true)
{
try
{
// 监控用户是否有输入信息
InputStream in = client.getInputStream();
// 如果用户有输入,则获取输入内容
InputStreamReader inreader = new InputStreamReader(in);
BufferedReader reader = new BufferedReader(inreader);
line = reader.readLine();
// 如果用户关闭聊天窗口
if (line == null)
{
// remove该用户,关闭线程
removeMyself();
return;
}
// 如果该用户有输入数据,则发送给其他用户
sendAllMsg("【" + uinfo.getUname() + " " + uinfo.getUip()
+ " 】 Say : " + line + "\r\n");
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
// 将消息散布
public void sendAllMsg(String msg) throws IOException
{
OutputStream out = null;
for (int i = 0; i < Services.allUser.size(); i++)
{
UserInfo user = Services.allUser.get(i);
// 如果是自己,则不需发送消息
if (uinfo.getUname().equals(user.getUname()))
{
continue;
}
Socket client = user.getClient();
out = client.getOutputStream();
OutputStreamWriter writer = new OutputStreamWriter(out);
writer.write(msg);
writer.flush();
}
}
// 删除下线用户
public void removeMyself() throws IOException
{
for (int i = 0; i < Services.allUser.size(); i++)
{
UserInfo user = Services.allUser.get(i);
// 如果当前用户关闭聊天窗口
if (user.getUname().equals(uinfo.getUname()))
{
// 向其他用户提示该用户下线
sendAllMsg("〖系统消息: " + user.getUname() + " 下线 !〗\r\n");
System.out.println("〖系统消息: " + user.getUname() + " 下线 !〗\r\n");
// remove当前用户
Services.allUser.remove(i);
}
}
}
}
StrUtil.java
import java.util.Random;
/**
* 工具类
*
* @author xKF24276 ruilin.xie
*
*/
public class StrUtil
{
public static String NumStr(int length)
{
StringBuffer numstr = new StringBuffer();
char[] cwords = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', 'A', 'B', 'V', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
'U', 'V', 'W', 'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5',
'6', '7', '8', '9' };
for (int i = 0; i < length; i++)
{
int ran = new Random().nextInt(cwords.length);
numstr.append(cwords[ran]);
}
return numstr.toString();
}
}
UserInfo.java
import java.net.Socket;
/**
* 用户信息
*
* @author xKF24276 ruilin.xie
*
*/
public class UserInfo
{
// 用户名
private String uname;
// 用户IP
private String uip;
// 客户端套接字
private Socket client;
public String getUname()
{
return uname;
}
public void setUname(String uname)
{
this.uname = uname;
}
public String getUip()
{
return uip;
}
public void setUip(String uip)
{
this.uip = uip;
}
public Socket getClient()
{
return client;
}
public void setClient(Socket client)
{
this.client = client;
}
}
分享到:
相关推荐
【描述】:“无聊,就写了个仿QQ聊天工具,实现了一台电脑多个用户及一用户和多人聊天功能等” 在描述中,我们可以推测这个聊天工具具备以下关键知识点: 1. **多用户支持**:为了实现一台电脑上的多个用户同时...
开发者提到“里面很粗糙,是无聊时做的”,这可能意味着这是一个个人项目,主要用于娱乐和学习,但同时也可供他人参考和交流。尽管可能在设计和实现上不够完善,但它依然可以作为一个基础,帮助其他开发者理解如何...
在“无聊专用聊天页面”这个场景下,尽管标题暗示这是一个供个人消遣的聊天室,但实际上,根据描述,它并不具备与其他用户交互的功能。这可能是一个单人使用的聊天应用或模拟器,让用户可以自言自语,表达想法,或者...
【标题】:“类似于QQ的局域网聊天工具” 在IT领域,开发一款“类似于QQ的局域网聊天工具”是一项有趣的挑战,它涉及到网络通信、多用户交互以及数据传输等核心技术。QQ作为中国最流行的即时通讯软件之一,其功能...
通过读取文本文件来存储参与者的姓名,然后在运行时将这些名字加载到内存中,随机选择并展示,避免了传统点名方式的繁琐和不准确性。 首先,让我们了解一下这个工具的工作原理。点名小工具的核心功能是读取文本文件...
标题中提到的"花半天时间写的一个简单的屏幕取色的工具",表明这可能是一个个人项目,用以提升技能或解决日常需求。 在IT行业中,开发这样的工具通常涉及到以下几个关键知识点: 1. **图形用户界面(GUI)设计**:...
使用该小工具时,玩家可以输入想要制造的道具类型和数量,然后工具会根据游戏内的制造公式,自动计算出所需的所有材料及其数量。这样,玩家就可以有针对性地收集材料,避免了无谓的浪费。同时,工具可能还具备一定的...
无聊的周末日记怎么写(范文6篇).pdf
“无聊软件”是经贸学院论坛追梦管理团队无聊工作室开发的一款方便实用、解闷的小工具,经过压缩,减小代码和结合网站实时更新的功能,使软件现有大小只有40K。 绿色、无毒、无需安装,方便实用。软件主要有“万能...
这个message 是自己无聊作的都是以女明星为背景的及不同的背景, 它们只能用在Grub4DOS下的GFX界面O(∩_∩)O~; 要用的时候最好把文件重命名成message,放在U盘根目录; 在菜单(menu.lst)中添加如下代码,还有不能...
完成部分功能 主要是给自己培养另一种思维方式 毕竟重复一样的东西很无趣 中国人不仅仅只会抄袭
标题中的“无聊写的小动画”可能是指作者出于兴趣或自我挑战,编写的一个简单的Android动画程序。描述中提到的“动画执行顺序”是Android动画系统中的一个关键概念,它涉及到如何控制动画的播放流程,确保动画效果...
标题“无聊的盒子_单片机_舵机_无聊的盒子”揭示了这是一个与电子制作相关的项目,其中涉及单片机和舵机技术。在这个项目中,“无聊的盒子”可能是一个创新的装置,通过舵机来实现其开关功能,增加了互动性和趣味性...
无聊自己的东西写的玩玩
而“工具”可能指的是开发者在构建这个游戏时所使用的开发工具,如Eclipse或IntelliJ IDEA,也可能包括用于图形渲染的Java库,如JavaFX或Swing。 在【压缩包子文件的文件名称列表】中,我们看到只有一个文件名...
无聊的关机cpp 无聊的关机cpp 无聊的关机cpp 无聊的关机cpp
数据访问层可能使用了ORM(对象关系映射)工具,如Hibernate或MyBatis,以便于在Java对象和数据库表之间建立映射,简化数据操作。 5. **安全机制**:考虑到描述中提到的安全性,系统可能内置了防止SQL注入、XSS攻击...
在标题“无聊写了个shell脚本”中,我们可以想象作者利用闲暇时间探索并实践了Shell脚本编写。描述中提到的“shell的loading效果”,指的是在执行命令或程序时显示动态加载的界面,这种效果可以提供用户反馈,增加...