一、单线程模式下:
客户端
package 聊天室.单线程模式;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
public class SingleThreadClient {
public static void main(String[] args) {
//1.服务端地址和端口
//127.0.0.1 4406
String ip="127.0.0.1";
int port = 4406;
//2.Socket
try {
Socket socket=new Socket ( ip,port );
//3.数据的发送
OutputStream out=socket.getOutputStream ();
PrintStream printStream=new PrintStream ( out );
printStream.println ( "服务器我来了" );
printStream.flush ();
//4.数据的接受
InputStream in=socket.getInputStream ();
Scanner scanner=new Scanner (in );
System.out.println ( "来自服务的数据:"+scanner.nextLine ());
} catch (IOException e) {
e.printStackTrace ( );
}
}
}
服务端
package 聊天室.单线程模式;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
public class SingleThreadServer {
public static void main(String[] args) {
//1.准备地址和端口
//127.0.0.1 4406
int port=4406;
try {
//2.创建serverSocket
ServerSocket serverSocket=new ServerSocket ( port );
System.out.println ("服务端启动了,运行在"+serverSocket.getLocalSocketAddress () );
//3.等待客户端连接
//阻塞方法
Socket socket=serverSocket.accept ();
//4.数据的接受
InputStream in=socket.getInputStream ();
Scanner scanner=new Scanner (in );
System.out.println ( "客户端说:"+scanner.nextLine ());
//5.数据的发送
OutputStream out=socket.getOutputStream ();
PrintStream printStream=new PrintStream ( out );
printStream.println ( "欢迎,欢迎" );
printStream.flush ();
} catch (IOException e) {
e.printStackTrace ( );
}
}
}
二、多线程模式下
客户端
从服务端读数据类
package 聊天室.单线程模式.多线程模式;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.util.Scanner;
public class ReadDataFromServerThread extends Thread {
private final Socket socket;
public ReadDataFromServerThread(Socket socket) {
this.socket=socket;
}
@Override
public void run() {
try {
InputStream in=this.socket.getInputStream ();
Scanner scanner=new Scanner ( in );
while(true){
String message=scanner.nextLine ();
System.out.println ("来自服务端的消息"+message );
}
} catch (IOException e) {
e.printStackTrace ( );
}
}
}
向服务端发数据类
package 聊天室.单线程模式.多线程模式;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.util.Scanner;
public class WriteDataToServerThread extends Thread{
private final Socket socket;
public WriteDataToServerThread(Socket socket) {
this.socket=socket;
}
@Override
public void run() {
try {
OutputStream out=this.socket.getOutputStream ();
PrintStream printStream=new PrintStream ( out );
Scanner scanner=new Scanner ( System.in );
while(true){
System.out.print("请输入:" );
String message=scanner.nextLine ();
printStream.println ( message );
printStream.flush ();
if(message.equals ( "bye" )){
break;
}
}
this.socket.close ();
} catch (IOException e) {
e.printStackTrace ( );
}
}
}
客户端
import java.io.IOException;
import java.net.Socket;
public class MultiThreadClient {
public static void main(String[] args) {
String defaultHost="127.0.0.1";
int defaultPort=4406;
String host=defaultHost;
int port = defaultPort;
for(String arg:args){
if(arg.startsWith ( "--port=" )){
String portStr=arg.substring ( "--port=".length () );
try {
port = Integer.parseInt ( portStr );
}catch(NumberFormatException e){
port=defaultPort;
}
}
if(arg.startsWith ( "--host=" )){
String hostStr=arg.substring ( "--host".length () );
host=hostStr;
}
}
try {
Socket socket=new Socket (host,port );
//发数据收数据
new WriteDataToServerThread(socket).start ();
new ReadDataFromServerThread(socket).start ();
} catch (IOException e) {
e.printStackTrace ( );
}
}
}
服务端
package 聊天室.单线程模式.多线程模式;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Map;
import java.util.Scanner;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
class ClientHander implements Runnable{
private static final Map<String,Socket> socketMap =new ConcurrentHashMap <> ( );
private final Socket client;
private String name;
public ClientHander(Socket client) {
this.client=client;
}
@Override
public void run() {
try {
InputStream in=this.client.getInputStream ();
Scanner scanner=new Scanner ( in );
while(true){
String line =scanner.nextLine ();
if(line.startsWith ( "register:" )){
String [] segments= line.split ( ":" );
if(segments.length==2 &&segments[0].equals ( "register" )){
String name=segments[1];
register(name);
}
continue;
}
if(line.startsWith ( "groupChat:" )){
String[] segments=line.split ( ":" );
if(segments.length==2&&segments[0].equals ( "groupChat" )){
String message=segments[1];
groupChat(message);
}
continue;
}
if(line.startsWith ( "privateChat:" )){
String[] segments=line.split ( ":" );
if(segments.length==3&&segments[0].equals ( "privateChat" )){
String name=segments[1];
String message=segments[2];
privateChat(name,message);
}
continue;
}
if(line .equalsIgnoreCase ( "bye" )){
quitChat();
break;
}
}
} catch (IOException e) {
e.printStackTrace ( );
}
}
private void quitChat() {
socketMap.remove ( this.name );
System.out.println (this.name+"下线了" );
printOnlineClient ();
}
private void privateChat(String name, String message) {
Socket socket=socketMap.get(name);
if(socket!=null){
sendMessage ( socket,message );
System.out.println (this.name+"说" +message);
}
}
private void groupChat(String message) {
for(Map.Entry<String,Socket> entry:socketMap.entrySet ()){
Socket socket=entry.getValue ();
if(socket==this.client){
continue;
}
sendMessage ( socket,this.name+"说" +message);
}
}
private void register(String name) {
this.name=name;
socketMap.put ( name,this.client );
System.out.println (name+"注册到系统中" );
sendMessage ( this.client,"欢迎"+name+"注册成功" );
printOnlineClient ();
}
private void printOnlineClient(){
System.out.println ("当前在线客户端有:"+socketMap.size ()+"个,名称类表如下:" );
for(String name :socketMap.keySet ()){
System.out.println (name );
}
}
//发送消息到指定客户端与服务端对等的消息
private void sendMessage(Socket socket, String message){
try {
OutputStream out=this .client.getOutputStream ();
PrintStream printStream=new PrintStream ( out );
printStream.println ( message );
printStream.flush ();
} catch (IOException e) {
e.printStackTrace ( );
}
}
}
public class MultiThreadServer {
public static void main(String[] args) {
int defaultPort=4406;
int port=defaultPort;
for(String arg:args){
if(arg.startsWith ( "--port=" )){
String portStr=arg.substring ( "--port=".length () );
try {
port = Integer.parseInt ( portStr );
}catch(NumberFormatException e){
port=defaultPort;
}
}
}
final ExecutorService executorService=Executors.newFixedThreadPool ( 2*Runtime.getRuntime ().availableProcessors () );
try {
ServerSocket serverSocket=new ServerSocket ( port) ;
System.out.println ("服务端启动,运行在:"+serverSocket.getLocalSocketAddress () );
while(true) {
final Socket socket = serverSocket.accept ( );
System.out.println ("客户端连接,来自:"+socket.getRemoteSocketAddress () );
executorService.execute ( new ClientHander (socket) );
}
} catch (IOException e) {
e.printStackTrace ( );
}finally {
executorService.shutdown ();
}
}
}