三次握手,四次挥手
Socket
群聊
客户端
package com.atguigu.net;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
/*
* 群聊
*/
public class Client4 {
public static void main(String[] args) throws UnknownHostException, IOException {
// 1、连接服务器
Socket socket = new Socket("127.0.0.1", 9999);
// 2、开启两个线程,一个收消息,一个发消息
SendThread st = new SendThread(socket);
ReceiveThread rt = new ReceiveThread(socket);
st.start();
rt.start();
// 等发送线程停下来再往下走
try {
st.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
// 等接收线程停下来,再往下走,断开连接
try {
rt.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
socket.close();
}
static class SendThread extends Thread {
private Socket socket;
public SendThread(Socket socket) {
super();
this.socket = socket;
}
public void run() {
try {
// 键盘输入
Scanner input = new Scanner(System.in);
OutputStream out = socket.getOutputStream();
PrintStream ps = new PrintStream(out);
while (true) {
// 从键盘输入
System.out.print("请输入要发送的消息:");
String content = input.nextLine();
// 给服务器发送
ps.println(content);
// 如果bye,就结束发送
if ("bye".equals(content)) {
break;
}
}
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
static class ReceiveThread extends Thread {
private Socket socket;
public ReceiveThread(Socket socket) {
super();
this.socket = socket;
}
public void run() {
try {
InputStream in = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(in);
BufferedReader br = new BufferedReader(isr);
while (true) {
String line = br.readLine();
if("bye".equals(line)){
break;
}
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
服务端
package com.atguigu.net;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Iterator;
public class Server4 {
private static ArrayList<Socket> online = new ArrayList<Socket>();
public static void main(String[] args) throws IOException {
//1、开启服务器
ServerSocket server = new ServerSocket(9999);
while(true){
//2、接收客户端的连接
Socket socket = server.accept();
//把这个客户端加入到online中
online.add(socket);
//每一个客户端独立的线程
MessageHandler mh = new MessageHandler(socket);
mh.start();
}
}
private static class MessageHandler extends Thread{
private Socket socket;
private String ip;
public MessageHandler(Socket socket) {
super();
this.socket = socket;
this.ip = socket.getInetAddress().getHostAddress();
}
public void run(){
//这个客户端的一连接成功,线程一启动,就可以告诉其他人我上线了
sendToOthers(ip+"上线了");
//(1)接收当前的客户端发送的消息
try {
InputStream in = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(in);
BufferedReader br = new BufferedReader(isr);
String content;
while((content = br.readLine()) !=null){
//收到一句,转发一句
sendToOthers(ip+"说:" + content);
if("bye".equals(content)){
//给自己发一句bye
OutputStream out = socket.getOutputStream();
PrintStream ps = new PrintStream(out);
ps.println("bye");
break;
}
}
sendToOthers(ip+"下线了");
} catch (IOException e) {
sendToOthers(ip+"掉线了");
}
}
//因为转发的代码也很长,独立为一个方法
public void sendToOthers(String str){
//遍历所有online的客户端
Iterator<Socket> iterator = online.iterator();
while(iterator.hasNext()){
Socket on = iterator.next();
if(!on.equals(socket)){//只给其他客户端转发
try {
OutputStream out = on.getOutputStream();
PrintStream ps = new PrintStream(out);
ps.println(str);
} catch (IOException e) {
//说明on这个客户端要么下线了,要么掉线了
iterator.remove();
}
}
}
}
}
}
UDP广播
package com.atguigu.net;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.util.Scanner;
public class GuangBo {
private volatile static boolean exit = false;
private static Scanner input = new Scanner(System.in);
public static void main(String[] args) throws IOException {
MulticastSocket socket = new MulticastSocket(9999);
InetAddress ip = InetAddress.getByName("230.0.0.1");
socket.joinGroup(ip);
socket.setLoopbackMode(false);
SendThread s = new SendThread(socket, ip);
ReceiveThread r = new ReceiveThread(socket);
s.start();
r.start();
try {
s.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
socket.close();
input.close();
}
static class SendThread extends Thread {
private MulticastSocket socket;
private InetAddress ip;
public SendThread(MulticastSocket socket, InetAddress ip) {
super();
this.socket = socket;
this.ip = ip;
}
public void run() {
try {
while (!exit) {
System.out.print("输入广播消息:");
String message = input.nextLine();
if ("bye".equals(message)) {
exit = true;
break;
}
byte[] data = (socket.getInetAddress().getHostAddress() + ":" + message).getBytes();
DatagramPacket dp = new DatagramPacket(data, data.length, ip, 9999);
socket.send(dp);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
static class ReceiveThread extends Thread {
private MulticastSocket socket;
public ReceiveThread(MulticastSocket socket) {
super();
this.socket = socket;
}
public void run() {
try {
while (!exit) {
byte[] data = new byte[1024];
DatagramPacket dp = new DatagramPacket(data, data.length);
socket.receive(dp);
String str = new String(data, 0, dp.getLength());
System.out.println(str);
}
} catch (IOException e) {
exit = false;
}
}
}
}