网络参考模型图:
UDP的实现:
无论发送还是接收端,都要有一个数据包,一个是发送,一个作接收,只能两个人单独聊天
发送端Send:
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Scanner;
public class udpSendTest {
public static void main(String[] args) throws Exception{
Scanner sc = new Scanner(System.in);
String shuju=null;
//建立udp包
DatagramSocket s = new DatagramSocket();
while (true){
System.out.println("请输入你要发送的消息:");
shuju=sc.nextLine();//可以接受其他字符
//将数据打包
byte[] bytes = shuju.getBytes();
String IP="192.168.27.20";
InetAddress ip = InetAddress.getByName(IP);
int port=8888;//在1025-2的16次方以内都行
DatagramPacket packet = new DatagramPacket(bytes,bytes.length,ip,port);
//打包完成,对象就将打包的数据发送
s.send(packet);
//当不想发送消息,就输入关闭
if(shuju.equals("关闭")){
System.out.println("发送端在3秒后即将关闭。。。");
Thread.sleep(3000);
break;
}
}
}
}
接收端Receive:
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class udpReceiveTest {
public static void main(String[] args) throws Exception{
//作为接受端,也要有一个udp对象,与发送端不同的是,接收端要在建立udp对象的时候写上端口号
DatagramSocket r = new DatagramSocket(8888);
//也要建立一个包,只不过是空数据包,就不需要写ip,和端口号
byte[] bytes = new byte[2048];
DatagramPacket packet = new DatagramPacket(bytes,bytes.length);
while (true){
//接收包
r.receive(packet);
//解析包
byte[] data = packet.getData();
int length = packet.getLength();
//包里是字节数据,要转成字符串
String s = new String(data,0,length);
//如果当发送端输入关闭,那么接受端也会停止接收
if(s.equals("关闭")){
System.out.println("接收端即将关闭");
break;
}
//在接受数据的时候,我还想知道是谁发送的数据,是什么时间发送的,所以可以根据包查询一下
InetAddress address = packet.getAddress();//获取发送端的原生ip地址,是包含用户名和ip号的
String hostName = address.getHostName();//从原生ip地址中获取用户名
String ip = address.getHostAddress();//从原生ip地址中获取ip
System.out.println("发送者的ip地址为:"+ip);
System.out.println("一位叫:"+hostName+"给您发送了一条信息");
System.out.println("信息内容是:"+s);
}
}
}
TCP的实现:多人聊天室
字节输入输出流的实现,加入多线程,可以让多人一起进入聊天室
客户端Client:
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Scanner;
public class tcpClient {
public static void main(String[] args) throws Exception{
Scanner sc = new Scanner(System.in);
String ip="192.168.26.12";
int port=2024;
//万一服务端崩溃或者未打开,凡是用到socket的地方都会报异常,需要处理一下
try{
//创建tcp的客户端
Socket socket = new Socket(ip,port);//传入ip和端口号
while (true){
System.out.println("请输入你要发送的内容:");
String neirong=sc.nextLine();
if(neirong.equals("关闭")){
System.out.println("客户端已关闭!");
break;
}
//得到管道的字节输出流
OutputStream os = socket.getOutputStream();
os.write(neirong.getBytes());
// //接受服务端的通知
InputStream is = socket.getInputStream();
byte[] bytes = new byte[2024];
int i = is.read(bytes);//读字节的时候,就不要while,因为外面有一层while,再套while读取会阻塞
String s = new String(bytes, 0, i);
System.out.println(s);
}
//释放资源
socket.close();
}catch (Exception e){
System.out.println("服务端异常,请检查服务端是否打开或者中断");
}
}
}
服务端Server:
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
public class tcpServer {
public static void main(String[] args) throws Exception{
//创建服务端对象
ServerSocket ss = new ServerSocket(2024);
//一直监听客户端
while (true){//如果不加while,只会监听一次,当客户端关闭,服务端也就关闭了
Socket socket = ss.accept();
new ClientThread(socket).start();
}
}
}
//如果只按照上面的写法,当客户端关闭,服务器也会自动关闭,这是不行的,服务器要一直监听,做服务功能
//所以设置一个线程,来来提供服务
class ClientThread extends Thread{
private Socket socket;
public ClientThread(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
System.out.println("============🙂欢迎来到TCP聊天室==============");
try{
InetAddress inetAddress = socket.getInetAddress();
String hostAddress = inetAddress.getHostAddress();
String hostName = inetAddress.getHostName();
System.out.println("ip:"+hostAddress+","+"用户"+hostName+"已上线🚀");
//通过客户端获取管道的输入流
InputStream is = socket.getInputStream();
//读取客户端的数据
int len=0;
byte[] bytes = new byte[2024];
while ((len=is.read(bytes))!=-1){
String s = new String(bytes, 0, len);
System.out.println("用户"+socket.getInetAddress().getHostName()+"发来一条信息:"+s);
//获取客户端的输出流,反馈客户端,服务端已经收到信息
OutputStream os = socket.getOutputStream();
String s1="服务端已收到!";
byte[] bytes1 = s1.getBytes();
os.write(bytes1);
}
}catch (Exception e){
// e.printStackTrace();// TODO:如果客户非正常关闭,说明客户端断开连接,要提示以下
System.out.println("================================");
System.out.println(socket.getInetAddress().getHostName()+"客户端已断开连接。。。。");
System.out.println("================================");
}
}
}