网络编程UDP和TCP
网络参考模型图:
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地址中获取ipSystem.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;}@Overridepublic 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("================================");}}
}