Java网络----Socket, 多线程实现内网多人聊天及一对一聊天
2017-08-22 13:25
896 查看
本文属于网络编程,才用Socket+多线程编程,实现使用控制台进行多人互动聊天,以及一对一互动聊天,
服务器端代码:
客户端代码:
客户端线程方法:
至此简单的多人聊天已经实现
运行服务器,再运行两台客户机,进行消息发送,通过服务器发送其他客户机,
效果如下:
服务器打印内容:
服务启动…..
服务连接….
当前有:1个客户端连接
服务连接….
当前有:2个客户端连接
Vip_HYP-PC说:我是客户A
Vip_HYP-PC说:我是客户B
客户机B打印内容:
Vip_HYP-PC说:我是客户A
我是客户B
当然这样的效果过于简陋,,比如我们可以让客户机来查看有几个用户?以及对某个特定的用户进行消息发送?想到这些,那就在服务器端先加上业务逻辑把.
先进行客户端改变:
删除hostName 定义实现,改为电脑ip标识:
MyThread方法修改
run方法增加username判断
接下来是服务器端代码修改:
首先mian方法中,对每次连接用户发送一个消息,进行用户名注册
重点到了,对获取到的消息进行判断执行:
贴出效果图:
服务器端代码:
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; import java.net.URLDecoder; import java.util.ArrayList; public class SimpleServer { //用于保存当前连接的用户 public static ArrayList<Socket> socketList=new ArrayList<Socket>(); /** * 服务器主函数 * @param args * @throws Exception */ public static void main(String[] args)throws Exception { //创建一个serverSocket,用于监听客户端Socket的连接请求 ServerSocket serverSocket = new ServerSocket(10002);//10002为此服务器的端口号 System.out.println("服务启动....."); //采用循环不断接收来自客户端的请求 while (true) { //每当接收到客户端的请求时,服务器端也对应产生一个Socket Socket socket = serverSocket.accept(); System.out.println("服务连接...."); // 把连接的客户端加入到list列表中 socketList.add(socket); System.out.println("当前有:"+socketList.size()+"个客户端连接"); //启动一个新的线程 //任务线程,每个连接用都有一个属于自己专用的任务线程 4000 //这个线程内会处理信息的发送和响应 new MyThread(socket,socketList).start(); } } } class MyThread extends Thread { //一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket。建立网络通信连接至少要一对端口号(socket) Socket client; ArrayList<Socket> clients; BufferedReader br; public MyThread(Socket client,ArrayList<Socket> clients)throws Exception { super(); this.client = client; this.clients = clients; br = new BufferedReader(new InputStreamReader(this.client.getInputStream())); } //把接收到的消息发送给各客户端 public void run() { try { String content=null; while(true){ //从某个客户端读取信息 if((content=br.readLine())!=null) { for(Socket socket:clients){ if(client!=socket){ //把读取到的消息发送给各个客户端 PrintWriter pw = new PrintWriter(socket.getOutputStream(), true); pw.println(content); } } content = URLDecoder.decode(content, "UTF-8"); System.out.println(content); } } }catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
客户端代码:
import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.net.Socket; import java.net.URLDecoder; public class Client { /** * @param args */ public static void main(String[] args) throws Exception { // TODO Auto-generated method stub //创建连接到本机,端口为10002的socket System.out.println("123"); Socket client = new Socket("192.168.1.49", 10002); new MyThread(client).start(); InputStream is = client.getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(is)); while (true) { String msg = br.readLine(); //对收到的信息进行解码 msg=URLDecoder.decode(msg, "UTF-8"); System.out.println(msg); } } }
客户端线程方法:
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.InetAddress; import java.net.Socket; import java.net.URLEncoder; import java.net.UnknownHostException; public class MyThread extends Thread { Socket client; //消息发送人名称,即本机的名称 String hostName = ""; public MyThread(Socket client) { super(); this.client = client; try { InetAddress addr = InetAddress.getLocalHost(); hostName =addr.getHostName().toString(); //获取本机计算机名称 } catch (UnknownHostException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } public void run() { // 发出消息 try { BufferedReader br = new BufferedReader(new InputStreamReader( System.in)); PrintWriter pw = new PrintWriter(client.getOutputStream(), true); // 把输入的内容输出到socket while (true) { String msg = br.readLine(); //对发出的消息进行编码 msg = URLEncoder.encode(hostName + "说:"+ msg, "UTF-8"); pw.println(msg); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
至此简单的多人聊天已经实现
运行服务器,再运行两台客户机,进行消息发送,通过服务器发送其他客户机,
效果如下:
服务器打印内容:
服务启动…..
服务连接….
当前有:1个客户端连接
服务连接….
当前有:2个客户端连接
Vip_HYP-PC说:我是客户A
Vip_HYP-PC说:我是客户B
客户机B打印内容:
Vip_HYP-PC说:我是客户A
我是客户B
当然这样的效果过于简陋,,比如我们可以让客户机来查看有几个用户?以及对某个特定的用户进行消息发送?想到这些,那就在服务器端先加上业务逻辑把.
先进行客户端改变:
删除hostName 定义实现,改为电脑ip标识:
//消息发送人名称 String userName = ""; //消息发送人IP地址,身份的唯一标识 String hostIP="";
MyThread方法修改
public MyThread(Socket client) { super(); this.client = client; try { InetAddress addr = InetAddress.getLocalHost(); hostIP=addr.getHostAddress().toString();//获取本机的计算机IP } catch (UnknownHostException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } }
run方法增加username判断
String msg = br.readLine(); //刚登录,进行用户名填写 if(userName.equals("")){ //对发出的消息进行编码 msg = URLEncoder.encode(hostIP+"__"+ msg, "UTF-8");//添加用户IP做唯一标识 pw.println(msg); }else{ //添加用户IP做唯一标识 msg = URLEncoder.encode(hostIP+"__"+userName + "__说:"+ msg, "UTF-8"); pw.println(msg); }
接下来是服务器端代码修改:
首先mian方法中,对每次连接用户发送一个消息,进行用户名注册
PrintWriter pw = new PrintWriter(socket.getOutputStream(), true); pw.println("请输入您的用户名,进行聊天"); BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); //创建用户名 String content = ""; if((content=br.readLine())!=null) { //以__拆分消息内容,ip,username content = URLDecoder.decode(content, "UTF-8"); String[] contents = content.split("__"); userNameMap.put(contents[0], contents[1]); }
重点到了,对获取到的消息进行判断执行:
if((content=br.readLine())!=null) { content = URLDecoder.decode(content, "UTF-8"); //以__拆分消息内容,ip,username+内容 String[] contents = content.split("__"); if(contents.length==3){ if(contents[2].equals("说:1")){//查看所有登录用户 for(Socket socket:clients){ if(client!=socket){//不是自身 PrintWriter pw = new PrintWriter(client.getOutputStream(), true); pw.println("用户名:"+userNameMap.get(socket.getInetAddress().toString())+",ip地址:"+socket.getInetAddress()); } } } } if(contents[2].equals("说:2")){//进行指定人聊天 //进行消息指定发送 } if(contents[2].equals("说:e")){//退出指定人聊天 //销毁两用户的一对一关联,未实现 }else{ for(Socket socket:clients){ if(client!=socket){ //把读取到的消息发送给各个客户端 PrintWriter pw = new PrintWriter(socket.getOutputStream(), true); pw.println(contents[1]+'['+contents[0]+']'+contents[2]); } } } } }
贴出效果图:
相关文章推荐
- 基于Socket的java网络编程(实现类似于QQ两人聊天的交互)
- java网络socket编程(七)之java中NIO实现聊天系统的群聊功能
- java网络编程一:Socket用法,简单模拟一对一聊天
- java中socket实现一对一聊天
- java网络编程一:Socket用法,简单模拟一对一聊天
- JAVA之旅(三十二)——JAVA网络请求,IP地址,TCP/UDP通讯协议概述,Socket,UDP传输,多线程UDP聊天应用
- java网络编程一:Socket用法,简单模拟一对一聊天
- java用socket和serversocket实现一对一聊天(java实现简单的TCP聊天程序)
- 利用网络Socket和多线程实现一个双向聊天
- 在java网络编程中实现服务器和客户端一对一的聊天
- 网络编程SOCKET实现一对一网络聊天,Ctrl+F5
- Java websocket + redis 实现多人单聊天室,多人多聊天室, 一对一聊天
- JAVA 多线程实现简单UDP一对一聊天
- JAVA之旅(三十二)——JAVA网络请求,IP地址,TCP/UDP通讯协议概述,Socket,UDP传输,多线程UDP聊天应用
- java网络编程一:模拟qq聊天功能,实现一对一聊天
- Java系列讲座二:Socket网络通信实现聊天软件项目讲解(UDP)
- Java系列讲座二:Socket网络通信实现聊天软件项目讲解(UDP)
- 【Java Socket】【Flex Socket】【Java 多线程】实现基本聊天功能demo
- 【java学习记录】12.用Socket网络访问方法,实现简单的网络聊天程序
- 一个java网络编程Socket的例子,实现Server与Client聊天