socket网络套节字---聊天室
一:服务端:
1.创建客户端:
package com.ywh.serversocket; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; import java.util.Set; public class LoginThread extends Thread { Socket client; boolean bl; //通过构造传入一个客户socket public LoginThread(Socket socket) { client=socket; } @Override public void run() { // TODO Auto-generated method stub try { //如果登录成功才运行发送消息的线程 LoginServer(); if(bl) { new SendThread(client).start(); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void LoginServer()throws Exception { //将连接后客户端输入传过来的用户名进行比对确认是否存在此用户 //先把传过来的用户名转换为string字符串 InputStream input=client.getInputStream(); byte[] bytes=new byte[1024]; input.read(bytes); String str=new String(bytes); System.out.println(str); //通过Set的add方法的返回值来确认用户名是否存在, //若用户名存在返回值为false,不存在则将新用户名加入用户名Set为true, boolean b=UserInfo.nickName.add(str); OutputStream output=client.getOutputStream(); if(b) { //当b=true,即新建用户成功时通知所有用户有新用户上线 //告知当前新用户创建成功 output.write("1".getBytes()); //将新用户的socket和用户名存入用户名map UserInfo.userMap.put(client, str); //获取用户socket Set<Socket> users=UserInfo.userMap.keySet(); for(Socket user:users) { OutputStream op=user.getOutputStream(); op.write((str+"已上线").getBytes()); } bl=true; }else { //若创建新用户失败,则返回false output.write("0".getBytes()); LoginServer(); bl=false; } } }
2.创建一个类用于存储登录用户的信息:
package com.ywh.serversocket; import java.net.Socket; import java.util.HashMap; import java.util.HashSet; import java.util.Set; public class UserInfo { //用来存储用户和用户名的Map public static HashMap<Socket, String> userMap=new HashMap<Socket, String>(); //用于存储用户名比对的Set public static Set<String> nickName=new HashSet<String>(); }
3.交互:发送线程
package com.ywh.serversocket; import java.io.IOException; import java.io.InputStream; import java.net.Socket; import java.util.Set; public class SendThread extends Thread { Socket client; public SendThread(Socket socket) { client = socket; } @Override public void run() { // TODO Auto-generated method stub while(true) { try { InputStream input=client.getInputStream(); byte[] bytes=new byte[1024]; input.read(bytes); String str=new String(bytes); Set<Socket> users=UserInfo.userMap.keySet(); for(Socket user:users) { if(user!=client) { user.getOutputStream().write ((UserInfo.userMap.get(client)+":"+str).getBytes()); } } } catch (IOException e) { // TODO Auto-generated catch block Set<Socket> users=UserInfo.userMap.keySet(); for(Socket user:users) { if(user!=client) { try { user.getOutputStream ().write((UserInfo.userMap.get(client)+"下线").getBytes()); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } UserInfo.nickName.remove (UserInfo.userMap.get(client)); UserInfo.userMap.remove(client); } } } } }
4.主方法,用于运行
package com.ywh.serversocket; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; public class Main { public static void main(String[] args) { // TODO Auto-generated method stub try { @SuppressWarnings("resource") ServerSocket serversocket=new ServerSocket(8088); System.out.println("服务器已启动..."); while(true) { Socket socket=serversocket.accept(); new LoginThread(socket).start(); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
服务端完成
二:客户端部分
1.客户端发送信息
package com.ywh.clientsocket; import java.io.IOException; import java.io.InputStream; import java.net.Socket; public class ClientReceive extends Thread { Socket client; public ClientReceive(Socket socket) { // TODO Auto-generated constructor stub client=socket; } @Override public void run() { // TODO Auto-generated method stub while(true) { try { InputStream input=client.getInputStream(); byte[] bytes=new byte[1024]; input.read(bytes); System.out.println(new String(bytes)); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
2.客户端接受信息
package com.ywh.clientsocket; import java.io.IOException; import java.net.Socket; import java.util.Scanner; public class ClientSend extends Thread { Socket client; public ClientSend(Socket socket) { // TODO Auto-generated constructor stub client=socket; } @Override public void run() { // TODO Auto-generated method stub @SuppressWarnings("resource") Scanner sc=new Scanner(System.in); while(true) { String str=sc.nextLine(); try { client.getOutputStream().write(str.getBytes()); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
3.客户端主方法
package com.ywh.clientsocket; import java.io.IOException; import java.io.InputStream; import java.net.Socket; import java.util.Scanner; public class Main { public static String ip = "192.168.10.32"; public static int port = 8088; static Scanner sc = new Scanner(System.in); public static void main(String[] args) { // TODO Auto-generated method stub // System.out.println("请输入IP地址"); // String ip=sc.nextLine().trim(); // System.out.println("请输入端口号"); // int port=sc.nextInt(); try { Socket user = new Socket(ip, port); System.out.println("连接服务器成功,请输入登录昵称"); String nickName = sc.nextLine(); while (nickName.equals("")) { System.out.println("昵称不能为空,请重新输入昵称"); nickName = sc.nextLine(); } Login(user,nickName); new ClientSend(user).start(); new ClientReceive(user).start(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static void Login(Socket user, String nickName) { try { user.getOutputStream().write(nickName.getBytes()); InputStream input = user.getInputStream(); byte[] bytes = new byte[1024]; input.read(bytes); String str = new String(bytes).trim(); while (str.equals("0")) { System.out.println("昵称重复,请重新输入昵称"); nickName = sc.nextLine(); while (nickName.equals("")) { System.out.println("昵称不能为空,请重新输入昵称"); nickName = sc.nextLine(); } user.getOutputStream().write(nickName.getBytes()); input = user.getInputStream(); bytes = new byte[1024]; input.read(bytes); str = new String(bytes); } if(str.equals("1")) { System.out.println("登录成功"); }else { System.out.println("服务器错误"); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }