宝安网站设计制作,wordpress界面404,深圳建设网站哪家强,网站网站开发公司2019独角兽企业重金招聘Python工程师标准 这几天看书看得java网络编程#xff0c;看到一个不错的#xff0c;适合新手的#xff0c;部分代码借鉴书上的#xff0c;可能有地方还不是很成熟#xff0c;不过可以借鉴一下#xff0c;分为客户端和服务端#x… 2019独角兽企业重金招聘Python工程师标准 这几天看书看得java网络编程看到一个不错的适合新手的部分代码借鉴书上的可能有地方还不是很成熟不过可以借鉴一下分为客户端和服务端话不多说贴代码很多都在注释中给出 客户端程序 YeekuProtocol类是一个帮助类用来定义协议字符串 /** * *description用来定义的协议字符/description * author Administrator * date 2013-11-26 * file CrazyitProtocol.java * category com.inspur.net.MultiThread.chat.server * version 1.0 * */ public interface YeekuProtocol { //定义协议字符串长度为2 int PROROCLO_LEN 2; //下面是一些协议字符串服务器和客户端交换的信息 //都应该在前、后添加这种特殊字符串。 String MSG_ROUND §γ; String USER_ROUND ∏∑; String LOGIN_SUCCESS 1; String NAME_REP -1; String PRIVATE_ROUND ★【; String SPLIT_SIGN ※; } clientThread线程类是客户端处理输入流的几个类 import java.io.BufferedReader; import java.io.IOException; /** *description客户端增加了让用户输入用户名的代码并且不允许用户名重复 *除此之外还可以根据用户的键盘输入来判断用户是否想发送私聊信息/description * author Administrator * date 2013-11-26 * file clientThread.java * category com.inspur.net.MultiThread.chat.client * version 1.0 * */ public class clientThread extends Thread{ //该线程负责处理输入流 BufferedReader br null; public clientThread(BufferedReader br){ this.br br; } public void run(){ //不断从输入流读取数据并且打印输出 String line null; try { while((linebr.readLine())!null){ System.out.println(line); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ if(br!null){ try { br.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } } client类主要负责客户端的一些操作 import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintStream; import java.net.Socket; import java.net.UnknownHostException; import javax.swing.JOptionPane; import com.inspur.net.MultiThread.chat.interfacefolder.YeekuProtocol; /** *description客户端增加了让用户输入用户名的代码并且不允许用户名重复 *除此之外还可以根据用户的键盘输入来判断用户是否想发送私聊信息/description * author Administrator * date 2013-11-26 * file client.java * category com.inspur.net.MultiThread.chat.client * version 1.0 * */ public class Client { private static final int SERVER_PORT 40001; private static final String ip 192.168.1.123; private Socket socket; private PrintStream ps ; private BufferedReader brServer; private BufferedReader keyIn; public void init(){ keyIn new BufferedReader(new InputStreamReader(System.in)); try { socket new Socket(ip,SERVER_PORT); ps new PrintStream(socket.getOutputStream()); brServer new BufferedReader(new InputStreamReader(socket.getInputStream())); String tip ; //采用循环不断弹出对话框要求输入用户名 while(true){ String userName JOptionPane.showInputDialog(tip输入用户名); //将用户名前后增加协议字符串 ps.println(YeekuProtocol.USER_ROUNDuserNameYeekuProtocol.USER_ROUND); //读取服务器的相应 String read brServer.readLine(); //如果用户重复开始下一次循环 if(read.equals(YeekuProtocol.NAME_REP)){ tip 用户名重复请刷新; continue; } //如果服务器返回成功,结束循环 if(read.equals(YeekuProtocol.LOGIN_SUCCESS)){ break; } } } catch (UnknownHostException e) { // TODO Auto-generated catch block System.out.println(找不到远程服务器确认服务已经启动); closeRs(); System.exit(1); e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block System.out.println(网络异常请重新登录); e.printStackTrace(); } new Thread(new clientThread(brServer)).run(); } //定义一个从键盘读入并向网络发送的方法 public void readAndSend(){ //不断从键盘读入 String line null; try { while((linekeyIn.readLine())!null){ if(line.indexOf(:)0 line.startsWith(//)){//如果以//开头则默认为私聊信息,后面必须输入要私聊的对象 line line.substring(2); ps.println(YeekuProtocol.PRIVATE_ROUNDline.split(:)[0]YeekuProtocol.SPLIT_SIGN line.split(:)[1]YeekuProtocol.PRIVATE_ROUND); } else{ ps.println(YeekuProtocol.MSG_ROUNDlineYeekuProtocol.MSG_ROUND); } } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void closeRs(){//关闭释放IO资源 try { if(keyIn!null){ keyIn.close(); } if(brServer!null){ brServer.close(); } if(ps!null){ ps.close(); } if(socket!null){ socket.close(); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static void main(String[] args) {//程序入口 Client client new Client(); client.init(); client.readAndSend(); } } 服务器端服务器端主要有YeekuMap类和server,serverThred类 YeekuMap类是服务端用来存储用户名和输入输出流之间的映射关系这样服务端就可以根据用户名来寻找相对应的socket实现私密通信利用map这一数据结构存储 import java.util.HashMap; import java.util.HashSet; import java.util.Set; /** * *description服务器端用来存储用户名和输入输出流之间的映射关系这样服务器就可以根据用户名来 *寻找相应的socket实现客户端之间的通信服务器只要获取gia用户名对应的输出流即可提供的这个HashMap类 *可以根据value获取key值或者是通过value删除key值而且不允许value的重复/description * author Administrator * date 2013-11-26 * file YeekuMap.java * category com.inspur.net.MultiThread.chat.server * version 1.0 * */ public class YeekuMapK,V extends HashMapK,V{ /** * */ private static final long serialVersionUID 1L; //根据value值来删除指定项 public void remonveByValue(Object value){ for(Object key : keySet()){ if(get(key)value){ remove(key); break; } } } //获取所有value组成的集合 public SetV valueSet(){ SetV result new HashSetV(); for(K key : keySet()){ //将每个key对应的value添加到result集合中 result.add(get(key)); } return result; } //通过value查找key public K getKeyByValue(V val){ //便利所有key组成的集合 for(K key : keySet()){ //如果指定key对应的value与被搜索的value相同 //则返回该key的值 if(get(key).equals(val) get(key)val){ return key; } } return null; } //重写HashMap的put方法该方法允许value的重复 public V put(K key , V value){ for(V val : valueSet()){ //如果指定的value与试图放入集合的value相同 //则抛出一个RuntimeException if(val get(key) val.equals(get(key))){ throw new RuntimeException(MyMap实例中不允许重复); } } return super.put(key, value); } } server类 import java.io.IOException; import java.io.PrintStream; import java.net.ServerSocket; import java.net.Socket; /** * *description服务器端程序建立ServerSocket监听客户端增加异常处理/description * author Administrator * date 2013-11-26 * file Server.java * category com.inspur.net.MultiThread.chat.server * version 1.0 * */ public class Server { //监听端口 private static final int SERVER_PORT 40001; //使用MyMap对象来存储每个客户名字和对应的输出流之间的关系 public static YeekuMapString ,PrintStream clients new YeekuMapString,PrintStream(); private Socket socket; public void init(){ try { ServerSocket serverSocket new ServerSocket(SERVER_PORT); while(true){ socket serverSocket.accept(); new Thread(new ServerThread(socket)).start(); } } catch (IOException e) { // TODO Auto-generated catch block System.out.println(服务器已经启动是否端口SERVER_PORT被占用); e.printStackTrace(); }finally{ if(socket!null){ try { socket.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.exit(1); } } } public static void main(String[] args) { Server server new Server(); server.init(); } } serverThraead类 import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintStream; import java.net.Socket; import com.inspur.net.MultiThread.chat.interfacefolder.YeekuProtocol; /** * *description服务器端程序处理客户端请求的实体类/description * author Administrator * date 2013-11-26 * file ServerThread.java * category com.inspur.net.MultiThread.chat.server * version 1.0 * */ public class ServerThread implements Runnable{ private Socket socket; private BufferedReader br null; private PrintStream ps null; public ServerThread(Socket socket){ this.socket socket; try { br new BufferedReader(new InputStreamReader(socket.getInputStream())); ps new PrintStream(socket.getOutputStream()); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void run() { // TODO Auto-generated method stub String line null; try { while((linebr.readLine())!null){ //如果读到以MyProtocol.USER ROUND开始和结束 //可以确定读到的是用户的用户名 if(line.startsWith(YeekuProtocol.USER_ROUND) line.endsWith(YeekuProtocol.USER_ROUND)){ String userName getRealMsg(line); if(Server.clients.containsKey(userName)){ System.out.println(重复); ps.println(YeekuProtocol.NAME_REP); }else{ System.out.println(成功); ps.println(YeekuProtocol.LOGIN_SUCCESS); Server.clients.put(userName, ps); } } //如果读到的行以YeekuProtocol.PRIVATE_ROUND开始结束 //可以确定是私聊信息私聊信息都以特定的流输出 else if(line.startsWith(YeekuProtocol.PRIVATE_ROUND) line.endsWith(YeekuProtocol.PRIVATE_ROUND)){ //得到真实信息 String userAndMsg getRealMsg(line); String User userAndMsg.split(YeekuProtocol.SPLIT_SIGN)[0]; String Msg userAndMsg.split(YeekuProtocol.SPLIT_SIGN)[1]; //获取私聊用户的输出流并发送私聊信息 Server.clients.get(User).println( Server.clients.getKeyByValue(ps)悄悄对你说:Msg); } //公聊的话向每个socket都发送 else{ //得到真实信息 String msg getRealMsg(line); //便利clients的每个输出流 for(PrintStream clientsPs : Server.clients.valueSet()){ clientsPs.println(Server.clients.getKeyByValue(ps)说msg); } } } } catch (IOException e) { // TODO Auto-generated catch block Server.clients.remonveByValue(ps); System.out.println(Server.clients.size()); //关闭io资源 try { if(br ! null){ br.close(); } if(ps ! null){ ps.close(); } if(socket !null){ socket.close(); } } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } e.printStackTrace(); } } //将读到的内容去掉前后的字符串恢复成真实数据 public String getRealMsg(String line){ return line.substring(YeekuProtocol.PROROCLO_LEN, line.length()-YeekuProtocol.PROROCLO_LEN); } } 以上就是这个简单实现我测试的时候时将他们导出成jar文件然后再cmd窗口运行jar文件此处在 MANIFEST.MF文件中应该加上一句Main-Class: 包名类名注意后面必须有个空格而且在结束之后要以换行结束shiftenter可能也有失误的地方本人新手勿喷 转载于:https://my.oschina.net/u/1034481/blog/179457