网络"/>
Java网络
本文属于网络编程,才用Socket+多线程编程,实现使用控制台进行多人互动聊天,以及一对一互动聊天,
服务器端代码:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.ServerSocket;
import java.Socket;
import java.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()+"个客户端连接");//启动一个新的线程 //任务线程,每个连接用都有一个属于自己专用的任务线程 //这个线程内会处理信息的发送和响应 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.Socket;
import java.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.InetAddress;
import java.Socket;
import java.URLEncoder;
import java.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 blocke1.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 blocke1.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,usernamecontent = 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]); } }}}
}
贴出效果图:
更多推荐
Java网络
发布评论