socket的客户端:
public class Client {
//socket封装了tcp协议的通讯细节,我们使用他可以与远端计算机建立TCPl链接
private Socket socket;
public Client(){
System.out.println("正在链接服务端。。。。");
try {
socket=new Socket("127.0.0.1",8088);
System.out.println("与服务端建立链接");
} catch (IOException e) {
e.printStackTrace();
}
}
//客户端开始工作的方法
public void start(){
//启动一个线程来读取服务端发送过来的消息
ServerHandler handler=new ServerHandler();
Thread thread=new Thread(handler);
thread.setDaemon(true);
thread.start();
try {
OutputStream os=socket.getOutputStream();
OutputStreamWriter osw=new OutputStreamWriter(os, StandardCharsets.UTF_8);
BufferedWriter bw=new BufferedWriter(osw);
PrintWriter pw=new PrintWriter(bw,true);
Scanner scanner=new Scanner(System.in);
while (true){
String line=scanner.nextLine();
if("exit".equalsIgnoreCase(line)){
break;
}
pw.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
//该线程负责读取服务端发送过啦IDE消息
private class ServerHandler implements Runnable{
@Override
public void run() {
try {
InputStream in=socket.getInputStream();
InputStreamReader isr=new InputStreamReader(in);
BufferedReader br=new BufferedReader(isr);
String line;
while ((line= br.readLine())!=null){
System.out.println("line = " + line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
Client client=new Client();
client.start();
}
}
public class Client { //socket封装了tcp协议的通讯细节,我们使用他可以与远端计算机建立TCPl链接 private Socket socket; public Client(){ System.out.println("正在链接服务端。。。。"); try { socket=new Socket("127.0.0.1",8088); System.out.println("与服务端建立链接"); } catch (IOException e) { e.printStackTrace(); }
} //客户端开始工作的方法 public void start(){ //启动一个线程来读取服务端发送过来的消息 ServerHandler handler=new ServerHandler(); Thread thread=new Thread(handler); thread.setDaemon(true); thread.start(); try { OutputStream os=socket.getOutputStream(); OutputStreamWriter osw=new OutputStreamWriter(os, StandardCharsets.UTF_8); BufferedWriter bw=new BufferedWriter(osw); PrintWriter pw=new PrintWriter(bw,true); Scanner scanner=new Scanner(System.in); while (true){ String line=scanner.nextLine(); if("exit".equalsIgnoreCase(line)){ break; } pw.println(line); } } catch (IOException e) { e.printStackTrace(); } } //该线程负责读取服务端发送过啦IDE消息 private class ServerHandler implements Runnable{ @Override public void run() { try { InputStream in=socket.getInputStream(); InputStreamReader isr=new InputStreamReader(in); BufferedReader br=new BufferedReader(isr); String line; while ((line= br.readLine())!=null){ System.out.println("line = " + line); } } catch (IOException e) { e.printStackTrace(); } } } public static void main(String[] args) { Client client=new Client(); client.start(); } }
socket的服务端
public class Server { //serversocket是运行在服务端的,他的主要的工作是 // 1.打开服务端口 // 2.监听该服务端口 一旦一个客户端链接,则返回一个socket实例,并通过这socket实例与连接的客户端进行交互 private ServerSocket serverSocket; private Collection<PrintWriter> allOut = new ArrayList<>(); public Server() { //ServerSocket要打开指定的端口,客户端就是通过该端口与服务端进行分链接 try { System.out.println("正在启动服务端。。。。"); serverSocket = new ServerSocket(8088); System.out.println("服务端启动完毕。。。。"); } catch (IOException e) { e.printStackTrace(); } } public void start(){ //accept()是一个阻塞方法,调用后开始等待,直到一个客户端与服务端建立链接为止 //此时该方法会立即返回一个socket,通过这sockcet与该客户端进行交互 while (true){ try { System.out.println("等待客户端链接。。。。"); Socket socket = serverSocket.accept(); System.out.println("一个客户端链接了。。。。"); //启动一个线程来处理与该客户端的交互 Runnable handelr=new ClientHandler(socket); Thread thread=new Thread(handelr); thread.start(); } catch (IOException e) { e.printStackTrace(); } } } //该线程负责与特定客户端交互 private class ClientHandler implements Runnable{ private Socket socket; private String host; //客户端的地址信息 public ClientHandler(Socket socket) { this.socket=socket; //通过socket获取远端计算机的地址信息 host=socket.getInetAddress().getHostAddress(); System.out.println("host = " + host); } @Override public void run() { PrintWriter pw=null; try { InputStream in=socket.getInputStream(); InputStreamReader isr=new InputStreamReader(in, StandardCharsets.UTF_8); BufferedReader br=new BufferedReader(isr); //通过socket获取输出流,用于给客户端发送消息 OutputStream os= socket.getOutputStream();; OutputStreamWriter osw=new OutputStreamWriter(os,StandardCharsets.UTF_8); BufferedWriter bw=new BufferedWriter(osw); pw = new PrintWriter(bw, true); synchronized (Server.this){ allOut.add(pw); } //广播通知所有客户端该用户上线了 sendMessage(host+"上线了,当前人数:"+allOut.size()); String line; while ((line=br.readLine())!=null){ System.out.println(host+"说:"+line); sendMessage(host+"说:"+line); } } catch (IOException e) { e.printStackTrace(); }finally { synchronized (Server.this){ allOut.remove(pw); } sendMessage(host+"下线了, 当前人数:"+allOut.size()); try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } } private void sendMessage(String message) { synchronized (Server.this){ for (PrintWriter pw:allOut) { pw.println(message); } } } } public static void main(String[] args) { Server server=new Server(); server.start(); } }
public class Server {
//serversocket是运行在服务端的,他的主要的工作是
// 1.打开服务端口
// 2.监听该服务端口 一旦一个客户端链接,则返回一个socket实例,并通过这socket实例与连接的客户端进行交互
private ServerSocket serverSocket;
private Collection<PrintWriter> allOut = new ArrayList<>();
public Server() {
//ServerSocket要打开指定的端口,客户端就是通过该端口与服务端进行分链接
try {
System.out.println("正在启动服务端。。。。");
serverSocket = new ServerSocket(8088);
System.out.println("服务端启动完毕。。。。");
} catch (IOException e) {
e.printStackTrace();
}
}
public void start(){
//accept()是一个阻塞方法,调用后开始等待,直到一个客户端与服务端建立链接为止
//此时该方法会立即返回一个socket,通过这sockcet与该客户端进行交互
while (true){
try {
System.out.println("等待客户端链接。。。。");
Socket socket = serverSocket.accept();
System.out.println("一个客户端链接了。。。。");
//启动一个线程来处理与该客户端的交互
Runnable handelr=new ClientHandler(socket);
Thread thread=new Thread(handelr);
thread.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//该线程负责与特定客户端交互
private class ClientHandler implements Runnable{
private Socket socket;
private String host; //客户端的地址信息
public ClientHandler(Socket socket) {
this.socket=socket;
//通过socket获取远端计算机的地址信息
host=socket.getInetAddress().getHostAddress();
System.out.println("host = " + host);
}
@Override
public void run() {
PrintWriter pw=null;
try {
InputStream in=socket.getInputStream();
InputStreamReader isr=new InputStreamReader(in, StandardCharsets.UTF_8);
BufferedReader br=new BufferedReader(isr);
//通过socket获取输出流,用于给客户端发送消息
OutputStream os= socket.getOutputStream();;
OutputStreamWriter osw=new OutputStreamWriter(os,StandardCharsets.UTF_8);
BufferedWriter bw=new BufferedWriter(osw);
pw = new PrintWriter(bw, true);
synchronized (Server.this){
allOut.add(pw);
}
//广播通知所有客户端该用户上线了
sendMessage(host+"上线了,当前人数:"+allOut.size());
String line;
while ((line=br.readLine())!=null){
System.out.println(host+"说:"+line);
sendMessage(host+"说:"+line);
}
} catch (IOException e) {
e.printStackTrace();
}finally {
synchronized (Server.this){
allOut.remove(pw);
}
sendMessage(host+"下线了, 当前人数:"+allOut.size());
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void sendMessage(String message) {
synchronized (Server.this){
for (PrintWriter pw:allOut) {
pw.println(message);
}
}
}
}
public static void main(String[] args) {
Server server=new Server();
server.start();
}
}