今天给各位分享javasocket多人聊天程序的知识,其中也会对java websocket聊天进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!
本文目录一览:
1、java socket 如何实现多用户通信?2、用Java实现一个人和几个不同的人私聊,用Socket实现3、java socket 多人单对单聊天 客户端的接受问题4、使用java socket如何建立多个多人的聊天室呢5、想求一个java聊天小程序,使用图形用户界面和socket通讯 功能:可以实现两个人私聊功能和多人聊天功能。
java socket 如何实现多用户通信?
你说的我明白。如果真正使用alohal协议的时候,所有的机器都可以检测网络电平变化的是吧?但是使用Java编写模拟程序的话,我们并不能可能检测电平的变换,只能通过一定的手段来模拟这个过程。如果你将一个包裹群发,这样所有的机器都可以接受这个包,这样就可以做到所有机器模拟检测电平变化的这个要求。我认为这个是最有说服力的模拟方法了。
线程需要使用Thread类型,重写里面的run函数,调用start()启动线程,具体可以搜索一把Thread,例子遍地都是。
UDP协议使用Socket类型,初始化的时候参数里面绑定(或者初始化好以后直接调用bind绑定端口,一般输出不用绑定,监听的时候需要绑定)。调用里面的getOutputStream得到输入流。调用getInputStream得到输入流。
OutputStream:输出流,用于向网络中输出数据。调用其中的write函数进行输出,函数的参数就是输出的byte数组。
InputStream: 输入流,用于接受网络里面的数据。调用其中的read可以得到输入的包。
String:你要输出的字符串,调用里面的getBytes可以得到String的byte数组。
其它的应该用不到什么了吧。
**********************************
1.发送字符串的话用byte[]就可以啊。用Socket类里面的getOutputStream可以获得一个发送数据的OutputStream类对象。这个类对象有一个函数write(byte[] b) 可以向网络写byte[]。一个字符串可以通过String类中的getBytes() 转化成byte[]。这样总该明白了吧
2.说一下我的思路:开一个端口A发送UDP包(广播给端口B),用于模拟发送,用一个线程(线程1)来跑。开端口B接受局域网内的包,用另外一个线程(线程2)来跑。在发送UDP包的时候,将变量mark置1,发送完置0。线程2如果接受到一个不是从本机发送的包,而且此时mark是1(说明本机和另外一个机器同时在发包),发生了冲突,表示线程1这次发送的包失败。
用Java实现一个人和几个不同的人私聊,用Socket实现
package API_Day09;
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.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
/**
* 控制台聊天程序
* 客户端应用程序
* @author Jacob
*
*/
public class chatClient
{
//客户端用于与服务端连接的Socket
private Socket clientSocket;
/**
* 构造方法,客户端初始化
*/
public chatClient()
{
try
{
/*
* socket(String host, int port)
* 地址: IP地址,用来定位网络上的计算机
* 端口: 用来找到远端计算机上用来连接的服务端应用程序
*/
clientSocket = new Socket(“www.easyaq.com”,12580);
}
catch (Exception e)
{
e.printStackTrace();
}
}
/**
* 客户端昵称验证方法
* @param 为Scanner
*/
private void inputNickName(Scanner scan) throws Exception
{
String nickName = null;
//创建输出流
PrintWriter pw = new PrintWriter(
new OutputStreamWriter(clientSocket.getOutputStream(),
“UTF-8”),true);
//创建输入流
BufferedReader br = new BufferedReader(
new InputStreamReader(
clientSocket.getInputStream(),”UTF-8″));
while(true)
{
System.out.println(“请创建您的昵称:”);
nickName = scan.nextLine();
if (nickName.trim().equals(“”))
{
System.out.println(“昵称不得为空”);
}
else
{
pw.println(nickName);
String pass = br.readLine();
if(pass!=null!pass.equals(“OK”))
{
System.out.println(“昵称已经被占用,请更换!”);
}
else
{
System.out.println(“你好!”+nickName+”可以开始聊天了”);
break;
}
}
}
}
/*
* 客户端启动的方法
*/
public void start()
{
try
{
/*
* 创建Scanner,读取用户输入内容
* 目的是设置客户端的昵称
*/
Scanner scanner = new Scanner(System.in);
inputNickName(scanner);
/*
* 将用于接收服务器端发送过来的信息的线程启动
*/
Runnable run = new GetServerMsgHandler();
Thread t = new Thread(run);
t.start();
/*
* 建立输出流,给服务端发信息
*/
OutputStream os = clientSocket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os,”UTF-8″);
PrintWriter pw = new PrintWriter(osw,true);
while(true)
{
pw.println(scanner.nextLine());
}
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
if(clientSocket !=null)
{
try
{
clientSocket.close();
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
}
/**
* 该线程体用来循环读取服务端发送过来的信息
* 并输出到客户端的控制台
* @param args
*/
class GetServerMsgHandler implements Runnable
{
@Override
public void run()
{
try
{
InputStream is = clientSocket.getInputStream();
InputStreamReader isr = new InputStreamReader(is,”UTF-8″);
BufferedReader br = new BufferedReader(isr);
String msgString = null;
while((msgString = br.readLine())!= null)
{
System.out.println(“服务端提示:”+ msgString);
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
public static void main(String[] args)
{
chatClient client = new chatClient();
client.start();
}
}
package API_Day09;
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.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* 控制台聊天程序
* 服务端应用程序
* @author Jacob
*
*/
public class chatServer
{
/**
* ServerSocket 是运行在服务端的Socket
* 用来监听端口,等待客户端的连接,
* 一旦连接成功就会返回与该客户端通信的Socket
*/
private ServerSocket serverSocket;
/**
* 创建线程池来管理客户端的连接线程
* 避免系统资源过度浪费
*/
private ExecutorService threadPool;
/**
* 该属性用来存放客户端之间私聊的信息
*/
private MapString,PrintWriter allOut;
/**
* 构造方法,服务端初始化
*/
public chatServer()
{
try
{
/*
* 创建ServerSocket,并申请服务端口
* 将来客户端就是通过该端口连接服务端程序的
*/
serverSocket = new ServerSocket(12580);
/*
* 初始化Map集合,存放客户端信息
*/
allOut = new HashMapString, PrintWriter();
/*
* 初始化线程池,设置线程的数量
*/
threadPool = Executors.newFixedThreadPool(10);
/*
* 初始化用来存放客户端输出流的集合,
* 每当一个客户端连接,就会将该客户端的输出流存入该集合;
* 每当一个客户端断开连接,就会将集合中该客户端的输出流删除;
* 每当转发一条信息,就要遍历集合中的所有输出流(元素)
* 因此转发的频率高于客户端登入登出的频率,
* 还是应该使用ArrayList来存储元素,仅限群聊,私聊不行
* allOut = new ArrayListPrintWriter();
*/
}
catch (Exception e)
{
e.printStackTrace();
}
}
/*
* 将客户端的信息以Map形式存入集合中
*/
private void addOut(String key,PrintWriter value)
{
synchronized(this)
{
allOut.put(key, value);
}
}
/*
* 将给定的输出流从共享集合中删除
* 参数为客户端nickName,作为Map的key键
*/
private synchronized void removeOut(String key)
{
allOut.remove(key);
System.out.println(“当前在线人数为:”+ allOut.size());
}
/*
* 将给定的消息转发给所有客户端
*/
private synchronized void sendMsgToAll(String message)
{
for(PrintWriter out: allOut.values())
{
out.println(message);
System.out.println(“当前在线人数为:”+ allOut.size());
}
}
/*
* 将给定的消息转发给私聊的客户端
*/
private synchronized void sendMsgToPrivate(String nickname,String message)
{
PrintWriter pw = allOut.get(nickname); //将对应客户端的聊天信息取出作为私聊内容发送出去
if(pw!=null)
{
pw.println(message);
System.out.println(“当前在线私聊人数为:”+ allOut.size());
}
}
/**
* 服务端启动的方法
*/
public void start()
{
try
{
while(true)
{
/*
* 监听10086端口
*/
System.out.println(“等待客户端连接… … “);
/*
* Socket accept() 这是一个阻塞方法,会一直在10086端口进行监听
* 直到一个客户端连接上,此时该方法会将与这个客户端进行通信的Socket返回
*/
Socket socket = serverSocket.accept();
System.out.println(“客户端连接成功! “);
/*
* 启动一个线程,由线程来处理客户端的请求,这样可以再次监听
* 下一个客户端的连接了
*/
Runnable run = new GetClientMsgHandler(socket);
threadPool.execute(run); //通过线程池来分配线程
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
/**
* 该线程体用来处理给定的某一个客户端的消息,循环接收客户端发送
* 的每一个字符串,并输出到控制台
* @author Jacob
*
*/
class GetClientMsgHandler implements Runnable
{
/*
* 该属性是当前线程处理的具体的客户端的Socket
* @see java.lang.Runnable#run()
*/
private Socket socket;
/*
* 获取客户端的地址信息
* private String hostIP;
*/
/*
* 获取客户端的昵称
*/
private String nickName;
/*
* 创建构造方法
*/
public GetClientMsgHandler(Socket socket)
{
this.socket = socket;
/*
* 获取远端客户的Ip地址信息
* 保存客户端的IP地址字符串
* InetAddress address = socket.getInetAddress();
* hostIP = address.getHostAddress();
*/
}
/*
* 创建内部类来获取昵称
*/
private String getNickName() throws Exception
{
try
{
//服务端的输入流读取客户端发送来的昵称输出流
InputStream iin = socket.getInputStream();
InputStreamReader isr =
new InputStreamReader(iin,”UTF-8″);
BufferedReader bReader = new BufferedReader(isr);
//服务端将昵称验证结果通过自身的输出流发送给客户端
OutputStream out = socket.getOutputStream();
OutputStreamWriter iosw =
new OutputStreamWriter(out,”UTF-8″);
PrintWriter ipw = new PrintWriter(iosw,true);
//读取客户端发来的昵称
String nameString = bReader.readLine();
while(true)
{
if(nameString.trim().length()==0)
{
ipw.println(“FAIL”);
}
if(allOut.containsKey(nameString))
{
ipw.println(“FAIL”);
}
else
{
ipw.println(“OK”);
return nameString;
}
nameString = bReader.readLine();
}
}
catch(Exception e)
{
throw e;
}
}
@Override
public void run()
{
PrintWriter pw = null;
try
{
/*
* 通过客户端的Socket获取客户端的输出流
* 用来将消息发送给客户端
*/
OutputStream os = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os,”UTF-8″);
pw = new PrintWriter(osw,true);
/*
* 将客户昵称和其所说的话作为元素存入共享集合HashMap中
*/
nickName = getNickName();
addOut(nickName, pw);
Thread.sleep(100);
/*
* 服务端通知所有客户端,某用户登录
*/
sendMsgToAll(“[系统通知]:欢迎**”+nickName+”**登陆聊天室!”);
/*
* 通过客户端的Socket获取输入流
* 读取客户端发送来的信息
*/
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is,”UTF-8″);
BufferedReader br = new BufferedReader(isr);
String msgString = null;
while((msgString = br.readLine())!=null)
{
//验证是否是私聊
if(msgString.startsWith(“@”))
{
/*
* 私聊格式:@昵称:内容
*/
int index = msgString.indexOf(“:”);
if(index =0)
{
//获取昵称
String name = msgString.substring(1,index);
String info = msgString.substring(index+1,msgString.length());
info = nickName + “对你说:”+ info;
//将私聊信息发送出去
sendMsgToPrivate(name, info);
//服务端不在广播私聊的信息
continue;
}
}
/*
* 遍历所有输出流,将该客户端发送的信息转发给所有客户端
*/
System.out.println(nickName+”说:”+ msgString);
sendMsgToAll(nickName+”说:”+ msgString);
}
}
catch (Exception e)
{
/*
* 因为Win系统用户的客户端断开连接后,br.readLine()方法读取
* 不到信息就会抛出异常,而Linux系统会持续发送null;
* 因此这里就不在将捕获的异常抛出了。
*/
}
finally
{
/*
* 当执行到此处时,说明客户端已经与服务端断开连接
* 则将该客户端存在共享集合中的输出流删除
*/
removeOut(nickName);
/*
* 通知所有客户端,某某客户已经下线
*/
sendMsgToAll(“[系统通知]:”+nickName + “已经下线了。”);
/*
* 关闭socket,则通过Socket获取的输入输出流也一同关闭了
*/
if(socket!=null)
{
try
{
socket.close();
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
}
}
public static void main(String[] args)
{
chatServer server = new chatServer();
server.start();
}
}
我的作业,供你参考
java socket 多人单对单聊天 客户端的接受问题
我也写过这样的程序,你的意思是只用一个socket然后让他接受信息吧,这样当然不行,既然有单对单的聊天,那么当客户A同时跟客户B客户C聊天的时候会使用到多个socket的.
我当时用的方法是用一个线程来监听来自其他客户的聊天请求的连接,当他接收到聊天请求的时候将socket直接传递给客户聊天线程ServerHold类来处理聊天事件,自己继续等待客户的连接.在程序中用一个Clent类来管理其他用户的信息 比如Clent有一个属性就是ServerHold类的实例
class Clent{
……
public ServerHold sh;
……
}
然后用一个ClentHost类
class ClentHost{
static Clent[] cs = new Clent[10];
public add(Clent clent){}
public del(Clent clent){}
public get(String name){}
}的实例来管理所有的Clent客户类
大体实例是:
class ServerWating extends Thread{
ServerSocket server;
Socket socket;
public ServerWating(){
try{
//监听端口
server = new ServerSocket(12345);
}catch(Exception e){
e.printStackTrace(System.out);
System.out.println(“对不起,监听线程出错”);
System.exit(0);
}
}
public void run(){
while(true){
try{
//等待用户连接
socket = server.accept();
//连接上后 将所得的socket 传递给ServerHold线程类并实例化 具体ServerHold类的参数你可以自己根据需求来写
ServerHold sh = new ServerHold(socket);
//启动该ServerHold线程
sh.start();
}catch(Exception e){
e.printStackTrace(System.out);
System.out.println(“对不起,监听线程出错”);
}
}
}
}
然后是与用户交互的类 ServerHold
class ServerHold extends Thread{
Socket socket;
public ServerHold(Socket socket){
this.socket = socket;
}
//用线程不停的读取对方发来的信息,避免信息的阻塞
public void run(){
try{
//根据socket新建输入流
while(true){
//读取对方发送的信息并从中获取对方的姓名,根据情况,或新建Clent然后将this(ServerHold类的本对象)添加到Clent或直接添加到已有的Clent
//读取对方发送的信息并反馈到程序
}
}catch(Exception e){
//当对方下线会出现错误时保证线程安全退出
}
}
//发送信息到对方,可以根据实际情况来确定方法的参数等内容,然后根据程序的需要直接调用
//在连接建立的时候,要发送一次自己的客户端信息,比如name什么的到对方以便其保存.
public void set(){
//根据socket取得输出流
}
}
当然,上面都是被动连接的,主动连接差不多,也是要根据连接后的socket来新建一个ServerHold类然后进行交互.
大体思想就是这样子的,当然 实现的时候会有好多困难,449775695我的QQ,有什么问题可以来问我.
使用java socket如何建立多个多人的聊天室呢
socket使用spring,就是一般应用使用Spring。
服务器端,使用多线程。
想求一个java聊天小程序,使用图形用户界面和socket通讯 功能:可以实现两个人私聊功能和多人聊天功能。
我只介绍思路:
使用websocket创建ws服务器,nat123解析一个地址,分配一个端口给他用,发布到外网。
客户端拨通地址 登陆 接入websocket服务,心跳机制要做好,上下线掉线更新列表,注册存储用户信息,更新用户列表。
客户端可以发起群聊、私聊、收发文件、分享,甚至发送服务器消息,然后反馈消息,响应远程服务事件。
这就是一个聊天软件所做的事情,我介绍websocket可以响应多平台,多端通信。
javasocket多人聊天程序的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于java websocket聊天、javasocket多人聊天程序的信息别忘了在本站进行查找喔。