本文主要介绍java Socket实现网页在线聊天的具体代码。本文中的示例代码非常详细,具有一定的参考价值。感兴趣的朋友可以参考一下。
本文分享一个满足在线web通信需求的例子。因为java Socket实现的网页版在线聊天功能,供大家参考。具体内容如下
实现步骤:
1.利用awt组件和socket实现简单的单客户端向服务器连续发送消息;
2.结合线程,多客户端连接服务器发送消息;
3.服务器将客户端消息转发给所有客户端,并在客户端显示;
4.将awt组件生成的窗口界面改为前端jsp或html显示界面,将java socket实现的客户端改为前端技术实现。
首先,这里实现了第一步的简单功能。难点在于:
1.没有使用过awt组件,没有使用过java相关的监控事件;
2.socket已经很久没有用于客户端和服务器的交互了,cs结构也没有真正开发出来。
实现功能的代码:
在线聊天客户端:
1.生成图形窗口界面的轮廓。
2.为大纲添加关闭事件。
3.向轮廓添加输入区域和内容显示区域。
4.向输入区域添加回车事件。
5.建立服务器连接并发送数据。
包chat.chat
导入Java . awt . borderlayout;
导入Java . awt . frame;
导入Java . awt . textarea;
导入Java . awt . textfield;
导入Java . awt . event . action event;
导入Java . awt . event . action listener;
导入Java . awt . event . window adapter;
导入Java . awt . event . window event;
导入Java . io . data output stream;
导入Java . io . io exception;
导入Java . net . socket;
导入Java . net . unknownhostexception;
/**
*在线聊天客户端1、生成图形窗口界面轮廓2、在轮廓中添加关闭事件3、在轮廓中添加输入区和内容显示区4、在输入区添加输入事件。
* 5.建立服务器连接并发送数据。
*
* @作者涂宗勋123
*
*/
公共类ChatClient扩展框架{
//用户输入区域
private TextField TF txt=new TextField();
//内容显示区域
private TextArea tarea=new TextArea();
私有套接字socket=null
//数据输出流
private data output stream data output stream=null;
公共静态void main(String[] args) {
新聊天客户端()。launch frame();
}
/**
*构建一个简单的图形窗口。
*
* @作者:涂宗勋
* @ Title:launch frame
* @param
* @返回void
* @日期2016年5月18日上午9点57分
* @次投掷
*/
公共void launch frame(){
setLocation(300,200);
this.setSize(200,400);
add(tfTxt,BorderLayout。南);
添加(tarea,BorderLayout。北);
pack();
//侦听图形界面窗口的关闭事件
this . addwindowlistener(new window adapter(){
@覆盖
public void window closing(window event e){
system . exit(0);
disConnect();
}
});
TF txt . addactionlistener(new TF lister());
set visible(true);
connect();
}
/**
*连接到服务器
*
* @作者:涂宗勋
* @Title:连接
* @param
* @返回void
* @日期2016年5月18日上午9点56分49秒
* @次投掷
*/
公共void connect() {
尝试{
//创建新的服务器连接
socket=新插座(' 127.0.0.1 ',8888);
//获取客户端输出流
data output stream=new data output stream(socket . get output stream());
System.out.println(“连接到服务器”);
} catch (UnknownHostException e) {
e . printstacktrace();
} catch (IOException e) {
e . printstacktrace();
}
}
/**
*关闭客户端资源。
*
* @作者:涂宗勋
* @Title:断开连接
* @param
* @返回void
* @日期2016年5月18日上午9点57分46秒
* @次投掷
*/
公共void disConnect() {
尝试{
data output stream . close();
socket . close();
} catch (IOException e) {
e . printstacktrace();
}
}
/**
*向服务器发送消息
*
* @作者:涂宗勋
* @Title:发送消息
* @param @param text
* @返回void
* @日期2016年5月18日上午9点57分56秒
* @次投掷
*/
私有void sendMessage(字符串文本){
尝试{
data output stream . write utf(text);
data output stream . flush();
} catch (IOException e1) {
E1 . printstacktrace();
}
}
/**
*图形窗口输入区监视回车事件。
*
* @作者涂宗勋123
*
*/
私有类TFLister实现ActionListener {
@覆盖
public void action performed(action event e){
String text=tfTxt.getText()。trim();
tarea.setText(文本);
TF txt . settext(');
//进入后将数据发送到服务器。
sendMessage(文本);
}
}
}
服务端:
包chat.chat
导入Java . io . data inputstream;
导入Java . io . eof exception;
导入Java . io . io exception;
导入Java . net . bind exception;
导入Java . net . server socket;
导入Java . net . socket;
/**
* java使用socket和awt组件简单实现在线聊天功能。客户端连接后,服务器可以持续向服务器发送消息。
*但不支持多个客户端同时连接,因为在代码中获得客户端连接后,客户端输入会一直被循环监听,造成拥塞。
*这样服务器就不能第二次监听其他客户端了。如果要实现的话,需要使用异步或者多线程。
*
* @作者涂宗勋123
*
*/
公共类ChatServer {
公共静态void main(String[] args) {
//服务器是否成功启动?
boolean isStart=false
//服务器套接字
ServerSocket ss=null
//客户端套接字
Socket socket=null
//服务器读取客户端数据输入流。
data inputstream data inputstream=null;
尝试{
//启动服务器
ss=new server socket(8888);
} catch (BindException e) {
System.out.println('端口已在使用');
//关闭程序
system . exit(0);
} catch(异常e) {
e . printstacktrace();
}
尝试{
isStart=true
while (isStart) {
布尔isConnect=false
//开始监控
socket=ss . accept();
System.out.println(“一个客户端连接”);
isConnect=true
while (isConnect) {
//获取客户端输入流
dataInputStream=新数据输入流(
socket . getinputstream());
//读取客户端传递的数据
string message=data inputstream . read utf();
System.out.println('客户端说:'消息');
}
}
} catch (EOFException e) {
System.out.println('客户端已关闭!');
} catch(异常e) {
e . printstacktrace();
}最后{
//关闭相关资源
尝试{
data inputstream . close();
socket . close();
} catch (IOException e) {
e . printstacktrace();
}
}
}
}
继续,在单客户端连接的基础上,这里的第二步需要实现多客户端连接,这也需要使用线程。每当有新的客户端连接时,服务器都需要启动新的线程进行处理,以解决之前循环读取造成的阻塞问题。
写线程通常有两种方式,集成Thread或者实现runnable接口。原则上,如果runnable可以实现,就不会被继承,因为实现接口的方式更加灵活。
相比之前,客户端代码没有变化,变成了服务器端代码,这里只贴服务器端代码:
java使用socket和awt组件以及多线程简单实现在线聊天功能服务端 :
多个客户端连接后,消息不断发送到服务器。与第一个版本相比,重点是多线程。服务器还没有实现转发功能,客户端只能看到自己输入的信息,看不到其他客户端发送的消息。
包chat.chat
导入Java . io . data inputstream;
导入Java . io . eof exception;
导入Java . io . io exception;
导入Java。网。绑定异常;
导入Java。网。服务器套接字;
导入Java。网。插座;
导入Java。网。套接字异常;
/**
* *
* @作者涂宗勋123
*
*/
公共类ChatServer {
公共静态void main(String[] args) {
新的ChatServer().start();
}
//是否成功启动服务端
私有布尔isStart=false
//服务端(电源)插座
私有服务器套接字ss=空
//客户端(电源)插座
私有套接字套接字=空
public void start() {
尝试{
//启动服务器
ss=新服务器套接字(8888);
} catch (BindException e) {
System.out.println('端口已在使用中');
//关闭程序
系统。退出(0);
} catch(异常e) {
e。printstacktrace();
}
尝试{
isStart=true
while (isStart) {
//启动监听
插座=ss。接受();
System.out.println("一个客户端连接");
//启动客户端线程
客户客户端=新客户端(插座);
新线程(客户端)。start();
}
} catch(异常e) {
e。printstacktrace();
}最后{
//关闭服务
尝试{
党卫军。close();
} catch (IOException e) {
e。printstacktrace();
}
}
}
/**
* 客户端线程
*
* @作者涂宗勋123
*
*/
类客户端实现可运行{
//客户端(电源)插座
私有套接字套接字=空
//客户端输入流
私有数据inputstream数据inputstream=null
私有布尔isConnect=false
公共客户端(套接字套接字){
this.socket=套接字
尝试{
isConnect=true
//获取客户端输入流
数据输入流=新数据输入流(套接字。getinputstream());
} catch (IOException e) {
e。printstacktrace();
}
}
@覆盖
公共无效运行(){
isConnect=true
尝试{
while (isConnect) {
//读取客户端传递的数据
字符串消息=数据输入流。读取utf();
System.out.println('客户端说:'消息);
}
} catch (EOFException e) {
System.out.println('客户端已关闭!');
} catch (SocketException e) {
'客户端已关闭!');
} catch(异常e) {
e。printstacktrace();
}最后{
//关闭相关资源
尝试{
数据输入流。close();
插座。close();
} catch (IOException e) {
e。printstacktrace();
}
}
}
}
}
上面主要介绍了利用线程使服务端实现了能够接收多客户端请求的功能,这里便需要客户端接收多客户端消息的同时还能把消息转发到每个连接的客户端,并且客户端要能在内容显示区域显示出来,从而实现简单的在线群聊。
在实现客户端转发,无非就是增加输出流;而之前客户端都只发不收,这里也需要更改客户端达到循环接收服务端消息的目的,因此也需要实现多线程。
在实现这个功能的时候,偶然想起随机生成验证码的功能,于是也灵机一动随机给每个客户端生成一个名字,从而在输出的时候看起来更加像是群聊,不仅有消息输出,还能看到是谁。
实现这些功能之后,基本上就可以几个人同时在线群聊了,因为代码中有主要的方法,因此可以把服务端和客户端都打成可执行冲突包,可参考我的另一篇博文:使用黯然失色创建Java 语言(一种计算机语言,尤用于创建网站)语言(一种计算机语言,尤用于创建网站)程序可执行冲突包
之后在桌面双击相应的冲突文件启动服务端和客户端即可,不需要再依赖黯然失色运行。
修改后的客户端代码如下:
包聊天聊天
导入Java。awt。borderlayout
导入Java。awt。框架;
导入Java。awt。textarea
导入Java。awt。textfield
导入Java。awt。事件。动作事件;
导入Java。awt。事件。动作监听器;
导入Java。awt。事件。窗口适配器;
导入Java。awt。事件。窗口事件;
导入Java。io。数据输入流;
导入Java。io。数据输出流;
导入Java。io。io异常;
导入Java。网。插座;
导入Java。网。unknownhostexception
导入Java。util。随机;
/**
* 在线聊天客户端步骤:
*1、生成图形窗口界面轮廓
*2、为轮廓添加关闭事件
*3、在轮廓中加入输入区域和内容展示区域
*4、为输入区域添加回车事件
* 5、建立服务端连接并发送数据
*
* @作者涂宗勋123
*
*/
公共类聊天客户端扩展框架{
/**
*
*/
private static final long serialVersionUID=1L;
//用户输入区域
private TextField TF txt=new TextField();
//内容展示区域
private TextArea tarea=new TextArea();
私有套接字套接字=空
//数据输出流
私有数据输出流数据输出流=null
//数据输入流
私有数据inputstream数据inputstream=null
私有布尔isConnect=false
Thread t receive=new Thread(新接收线程());
字符串名称="";
公共静态void main(String[] args) {
聊天客户端聊天客户端=新聊天客户端();
聊天客户端。create name();
聊天客户端。发射帧();
}
/**
* 建立一个简单的图形化窗口
*
* @作者:涂宗勋
* @ Title:发射架
* @param
* @返回空的
* @日期2016年5月18日上午9点57分
* @次投掷
*/
公共void启动框架(){
setLocation(300,200);
this.setSize(200,400);
add(tfTxt,BorderLayout .南);
添加(tarea,BorderLayout .北);
//根据窗口里面的布局及组件的首选尺寸来确定设计的最佳大小
pack();
//监听图形界面窗口的关闭事件
这个。addwindowlistener(新窗口适配器(){
@覆盖
公共void窗口关闭(窗口事件e){
系统。退出(0);
disConnect();
}
});
TF txt。addactionlistener(新的TF lister());
//设置窗口可见
设置可见(真);
connect();
//启动接受消息的线程
不接收。start();
}
/**
* 连接服务器
*
* @作者:涂宗勋
* @标题:连接
* @param
* @返回空的
* @日期2016年5月18日上午9点56分49秒
* @次投掷
*/
公共void connect() {
尝试{
//新建服务端连接
插座=新插座(' 127.0.0.1 ',8888);
//获取客户端输出流
数据输出流=新的数据输出流(套接字。获取输出流());
数据输入流=新数据输入流(套接字。getinputstream());
System.out.println('连上服务端');
isConnect=true
} catch (UnknownHostException e) {
e。printstacktrace();
} catch (IOException e) {
e。printstacktrace();
}
}
//生成随机的客户端名字
public void createName() {
String[] str1={ '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 ',' 1 ',' 2 ',' 3 ',' 4 ',' 5 ',' 6 ',' 7 ',' 8 ',
9 ',' 0 ',' 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 ' };
Random ran=new Random();
for(int I=0;i6;i ) {
//long num=数学。圆(数学。random()*(str 1。长度-0)0);
//int n=(int)num;
int n=ran。nextint(str 1。长度);
if (n str1.length) {
string str=str 1[n];
名称=名称字符串;
System.out.println(名称);
}否则{
I-;
继续;
}
}
this.setTitle(名称);
}
/**
* 关闭客户端资源
*
* @作者:涂宗勋
* @标题:断开连接
* @param
* @返回空的
* @日期2016年5月18日上午9点57分46秒
* @次投掷
*/
公共无效断开(){
尝试{
isConnect=false
//停止线程
不接收。join();
} catch (InterruptedException e) {
e。printstacktrace();
}最后{
尝试{
if (dataOutputStream!=null) {
数据输出流。close();
}
如果(插座!=null) {
插座。close();
套接字=空
}
} catch (IOException e) {
e。printstacktrace();
}
}
}
/**
* 向服务端发送消息
*
* @作者:涂宗勋
* @标题:发送消息
* @param @param text
* @返回空的
* @日期2016年5月18日上午9点57分56秒
* @次投掷
*/
私有无效发送消息(字符串文本){
尝试{
数据输出流。写入utf(名称':'文本);
数据输出流。flush();
} catch (IOException e1) {
E1。printstacktrace();
}
}
/**
* 图形窗口输入区域监听回车事件
*
* @作者涂宗勋123
*
*/
私有类TFLister实现动作监听器{
@覆盖
已执行公共无效操作(操作事件e){
String text=tfTxt.getText().trim();
//清空输入区域信息
TF txt。settext(');
//回车后发送数据到服务器
发送消息(文本);
}
}
私有类接收线程实现可运行{
@覆盖
公共无效运行(){
尝试{
while (isConnect) {
字符串消息=数据输入流。读取utf();
系统。出去。println(消息);
string txt=tarea。gettext();
如果(txt!=null!''.等于(txt。trim())({
message=tarea。gettext()' \ n '消息;
}
tarea.setText(消息);
}
} catch (IOException e) {
e。printstacktrace();
}
}
}
}
修改后的服务端代码如下:
包聊天聊天
导入Java。io。数据输入流;
导入Java。io。数据输出流;
导入Java。io。eof异常;
导入Java。io。io异常;
导入Java。网。绑定异常;
导入Java。网。服务器套接字;
导入Java。网。插座;
导入Java。网。套接字异常;
导入Java。util。ArrayList
导入Java。util。列表;
/**
* java使用(电源)插座和水的高级废水处理高次废水处理组件以及多线程简单实现在线聊天功能服务端:
* 实现服务端把接收到的客户端信息转发到所有连接的客户端,并且让客户端读取到这些信息并显示在内容显示区域中。
*
* @作者涂宗勋123
*
*/
公共类ChatServer {
公共静态void main(String[] args) {
新的ChatServer().start();
}
//是否成功启动服务端
私有布尔isStart=false
//服务端(电源)插座
私有服务器套接字ss=空
//客户端(电源)插座
私有套接字套接字=空
//保存客户端集合
list client clients=new ArrayList client();
public void start() {
尝试{
//启动服务器
ss=新服务器套接字(8888);
} catch (BindException e) {
System.out.println('端口已在使用中');
//关闭程序
系统。退出(0);
} catch(异常e) {
e。printstacktrace();
}
尝试{
isStart=true
while (isStart) {
//启动监听
插座=ss。接受();
System.out.println("一个客户端连接");
//启动客户端线程
客户客户端=新客户端(插座);
新线程(客户端)。start();
clients.add(客户端);
}
} catch(异常e) {
e。printstacktrace();
}最后{
//关闭服务
尝试{
党卫军。close();
} catch (IOException e) {
e。printstacktrace();
}
}
}
/**
* 客户端线程
*
* @作者涂宗勋123
*
*/
私有类客户端实现可运行{
//客户端(电源)插座
私有套接字套接字=空
//客户端输入流
私有数据inputstream数据inputstream=null
//客户端输出流
私有数据输出流数据输出流=null
私有布尔isConnect=false
公共客户端(套接字套接字){
this.socket=套接字
尝试{
isConnect=true
//获取客户端输入流
数据输入流=新数据输入流(套接字。getinputstream());
//获取客户端输出流
数据输出流=新数据输出流(
插座。获取输出流());
} catch (IOException e) {
e。printstacktrace();
}
}
/**
* 向客户端群发(转发)数据
*
* @作者:涂宗勋
* @Title: sendMessageToClients
* @param @param消息
* @返回空的
* @日期2016年5月18日上午11点28分10秒
* @次投掷
*/
公共void sendMessageToClients(字符串消息){
尝试{
数据输出流。写utf(消息);
} catch (SocketException e) {
} catch (IOException e) {
e。printstacktrace();
}
}
@覆盖
公共无效运行(){
isConnect=true
客户端c=空;
尝试{
while (isConnect) {
//读取客户端传递的数据
字符串消息=数据输入流。读取utf();
System.out.println('客户端说:'消息);
for(int I=0;我的客户。size();i ) {
c=客户。get(I);
c.sendMessageToClients(消息);
}
}
} catch (EOFException e) {
System.out.println('客户端已关闭!');
} catch (SocketException e) {
如果(c!=null) {
客户。删除(c);
}
'客户端已关闭!');
} catch(异常e) {
e。printstacktrace();
}最后{
//关闭相关资源
尝试{
if (dataInputStream!=null) {
数据输入流。close();
}
如果(插座!=null) {
插座。close();
套接字=空
}
} catch (IOException e) {
e。printstacktrace();
}
}
}
}
}
就先为大家介绍到这里,之后如果有新的内容再为大家进行更新。
关于网页在线聊天功能的实现大,大家还可以参考一下几篇文章进行学习:
Java 语言(一种计算机语言,尤用于创建网站)语言(一种计算机语言,尤用于创建网站)实现一个简单TCPSocket聊天室功能分享
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家可以继续关注我们的更多精彩内容。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。