网络编程(二)

服务端和客户端无限通信(需要线程)(基于TPC协议的网络编程)

Cilent

public class Client {
      public static void main(String[] args) {
  		try {
  			Socket socket = new Socket("127.0.0.1", 9000);
  			System.out.println("客户端连接");
  			//接收服务器的信息
  			InputStream inputStream = socket.getInputStream();
  			BufferedInputStream bis = new BufferedInputStream(inputStream);
  			//给服务器发送数据
  			OutputStream outputStream = socket.getOutputStream();
  		    //控制台输入信息
  			Scanner input= new Scanner(System.in);
  			
  			BufferedOutputStream bos = new BufferedOutputStream(outputStream);
  		    
  			new ReadThread(bis).start();
  		    while(true) {
  		    	String next = input.next();
  		    	bos.write(next.getBytes());
  		    	bos.flush();
  		    }
  		
  		
  		} catch (IOException e) {
  			// TODO Auto-generated catch block
  			e.printStackTrace();
  		}
  		
	}
}

Server

public class Server {

	public static void main(String[] args)  {
		
	 try {
		 ServerSocket server = new ServerSocket(9000);
		 System.out.println("等待连接");
		 //连接客户端
		 Socket socket = server.accept();
		 System.out.println("连接成功");
		 //获取输出流对象
		 OutputStream outputStream = socket.getOutputStream();
		 BufferedOutputStream bos = new BufferedOutputStream(outputStream);
		 //获取客户端的信息
		 BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
		  //控制台输入信息
		 Scanner input = new Scanner(System.in);
		 new ReadThread(bis).start();
		 
		 while(true) {
			String next = input.next();
			bos.write(next.getBytes());			 
			bos.flush();
		 }
		 
		 
	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	}
}

ReadThread线程

public class ReadThread extends Thread {

	BufferedInputStream bis;

	public ReadThread(BufferedInputStream bis) {
		super();
		this.bis = bis;
	}
	
	@Override
	public void run() {
		
		while(true) {
			int i=0;
			byte[] b =new byte[1024];
			try {
				while((i=bis.read(b))!=-1) {
					String str = new String(b,0,i);
					System.out.println(str);
				}
				
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}			
		}	
	}
	
}

效果图
Server
在这里插入图片描述Client
在这里插入图片描述

服务端向客户端群发(基于TPC协议的网络编程)

Client(开启三个,代码都一样)

public class Client1 {

	public static void main(String[] args) throws Exception {
		   Socket socket =  new Socket("127.0.0.1",9000);
		   System.out.println("客户端连接......");
		   BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));			
			new ReadThread(in).start();			
	}
}

Server

public class Server {
	//创建集合存储客户端的socket
    static List<Socket> collections = new ArrayList<>();
	public static void main(String[] args) throws Exception {
		ServerSocket server = new ServerSocket(9000);		
		System.out.println("等待连接");
	    Scanner input =new Scanner(System.in);
	//  加线程  为了遍历取出connections中的socket 
	    new QunFaThread(input).start();
	    while(true){
	    	//开始连接客户端
			Socket socket = server.accept();
			System.out.println("连接的客户端:"+socket);
			//存储客户端的socket
			collections.add(socket);
			System.out.println("集合中的元素------"+collections);
		    //获取客户端发来的信息
		   // BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));	    
	    }
	}	
	public static void sendAll(String s) throws Exception{
		 if(null != collections){
			 for (int i = 0; i < collections.size(); i++) {
				 Socket socket = collections.get(i);
				 PrintWriter pw = new PrintWriter(socket.getOutputStream());
				 pw.println(s);
				 pw.flush();
			}
		 }
	}
}

ReadThread

public class ReadThread extends Thread{
	BufferedReader br;	
public ReadThread(BufferedReader br) {
		super();
		this.br = br;
	}
public void run() {
	while(true){
	  try {
		String readLine = br.readLine();
		System.out.println(readLine);
	} catch (IOException e) {
		e.printStackTrace();
		}
	}
}
}

QunFaThread

public class QunFaThread extends Thread{
    Scanner input;	
	public QunFaThread(Scanner input) {
		super();
		this.input = input;
	}
	public void run() {
		while(true){
			String s = input.nextLine();
		 try {
			Server.sendAll(s);
		} catch (Exception e) {
			
			e.printStackTrace();
		}
		}	 
	}
}

效果图:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

客户端向客户端群发(基于TPC协议的网络编程)

客户端–服务端–客户端
Client(开启三个客户端)

public class Client1 {

	public static void main(String[] args) throws Exception {
		   Socket socket =  new Socket("127.0.0.1",9000);
		   System.out.println("客户端连接......");
		   BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
		   PrintWriter pw = new PrintWriter(socket.getOutputStream());
		   Scanner input = new Scanner(System.in);
		  new ReadThread(in).start();
		  while(true){
				pw.println(input.nextLine());
				pw.flush();
			}
	}
}

Server

public class Server {

	//创建集合存储客户端的socket
    static List<Socket> collections = new ArrayList<>();
	public static void main(String[] args) throws Exception {
		
		ServerSocket server = new ServerSocket(9000);
		
		System.out.println("等待连接");
	    Scanner input =new Scanner(System.in);
	
	  
	    while(true){
	    	//开始连接客户端
			Socket socket = server.accept();
			System.out.println("连接的客户端:"+socket);
			//存储客户端的socket
			collections.add(socket);
			System.out.println("集合中的元素------"+collections);
		    
		    new QunFaThread(socket).start();
	    }
	}
	
	public static void sendAll(String s) throws Exception{
		 if(null != collections){
			 for (int i = 0; i < collections.size(); i++) {
				 Socket socket = collections.get(i);
				 PrintWriter pw = new PrintWriter(socket.getOutputStream());
				 pw.println(s);
				 pw.flush();
			}
		 }
	}
}

ReadThread

public class ReadThread extends Thread{
	BufferedReader br;
	
public ReadThread(BufferedReader br) {
		super();
		this.br = br;
	}

public void run() {
	while(true){
	  try {
		String readLine = br.readLine();
		System.out.println(readLine);
	} catch (IOException e) {
		e.printStackTrace();
		}
	}
}
}

QunFaThread

public class QunFaThread extends Thread{
	Socket socket;	
	public QunFaThread( Socket socket) {
		super();
		this.socket = socket;
	}
	public void run() {
		   while(true){
			//得到输入流
				try {
					BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
					String s = br.readLine();
						Server.sendAll(s);
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}			
	}
}
}

效果图:在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

客户端和客户端的私聊(基于TPC协议的网络编程)

Client

public class Client1 {

	public static void main(String[] args) throws UnknownHostException, IOException {
		//输入自己的名称
		Scanner input = new Scanner(System.in);
		System.out.println("请输入您的姓名:");
		String name = input.next();
		Socket socket = new Socket("127.0.0.1",9001);
		//接收服务端发来的消息
		BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
		//将自己的姓名传过去
		PrintWriter pw = new PrintWriter(socket.getOutputStream());
		pw.println(name);
	    pw.flush();
	    
	    new ReadThread(br).start();
	     
	    while(true) {
	     //给服务端发送消息		
	     PrintWriter pw2 = new PrintWriter(socket.getOutputStream());
	     pw2.println(input.next());
	     pw2.flush();
	     }

	}
}

Server

public class Server {

	static ArrayList<Socket> socketList = new ArrayList<>(); 
	static ArrayList<QunFaThread> threadList = new ArrayList<>(); 
	
	public static void main(String[] args) throws Exception {
		
		@SuppressWarnings("resource")
		ServerSocket serverSocket = new ServerSocket(9001);
		System.out.println("等待连接");
		while(true) {
			//连接客户端
			Socket socket = serverSocket.accept();
			socketList.add(socket);
			System.out.println("连接成功-----------------------"+socket);
			BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
			//获取客户端的名字
			String name = br.readLine();
			QunFaThread qf = new QunFaThread(name,socket);		
			threadList.add(qf);
			//开启线程
			qf.start();
		}
		
	}
	//群发
	public static void sendAll(String str) throws IOException {
		if(null!=socketList) {
			for (int i = 0; i < socketList.size(); i++) {
				Socket socket = socketList.get(i);
                //向所有的客户端发送消息
				PrintWriter pw = new PrintWriter(socket.getOutputStream());				
				pw.println(str);
				pw.flush();
			}
			
		}
		else {
			System.out.println("没有客户端连接服务器");
		}
	}
	
	//私聊
	public static  void sendOne(String fromName,String toName,String line) throws IOException {
		
		if(null!=socketList) {
			
			for (int i = 0; i < socketList.size(); i++) {
				
				QunFaThread qf = threadList.get(i);
				PrintWriter pw = new PrintWriter(new OutputStreamWriter(qf.getSocket().getOutputStream()));				
				if(qf.getFromName().equals(toName)){
					pw.println(line);
				    pw.flush();
				}
				else {
					System.out.println("查无此人");
				}				
			}			
		}	
	}
}

ReadThread

public class ReadThread extends Thread {
	BufferedReader br;

	public ReadThread(BufferedReader br) {
		super();
		this.br = br;
	}

	public void run() {
		while (true) {
			try {
				String readLine = br.readLine();
				System.out.println(readLine);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

QunFaThread

public class QunFaThread extends Thread{

	String fromName;
	Socket socket;
	public QunFaThread(String fromName, Socket socket) {
		super();
		this.fromName = fromName;
		this.socket = socket;
	}	
	public String getFromName() {
		return fromName;
	}
	public void setFromName(String fromName) {
		this.fromName = fromName;
	}
	public Socket getSocket() {
		return socket;
	}
	public void setSocket(Socket socket) {
		this.socket = socket;
	}



	@Override
	public void run() {	
	   while(true) {		 		   
		   try {
			BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
		     
		    //获取客户端发来的信息
			String readLine = br.readLine();
		   //@one@xiaoming@nihao
			if(readLine.startsWith("@one")) {
				//私聊
				String[] s = readLine.split("@");
				Server.sendOne(fromName, s[2], s[3]);
			}
			else {
				//群发
				Server.sendAll(readLine);
			}
		   } catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}		   
	   }
	}	
}

效果图
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

关闭Socket

Socket的close()方法,关闭socket的同时也会关闭由socket创建的流
调用流的close方法关闭socket获取的输入或输出流的同时,也会关闭对应的socket。
在这里插入图片描述

UPD协议

定义: UDP协议是提供非连接的、面向事务的、简单不可靠的通信服务的传输层协议

基于UDP协议的网络编程:

DatagramSocket
定义:用于发送和接收数据报包的套接字
构造方法:

DatagramSocket ds=new DatagramSocket(); 
DatagramSocket ds=new DatagramSocket(int prot);//端口号
DatagramSocket ds=new DatagramSocket(int port, InetAddress laddr);//端口号 ip地址 

方法:
在这里插入图片描述
DatagramPacket
包含要发送或接收的数据
包含数据报发送或接收的地址信息
构造方法

DatagramPacket  dp = DatagramPacket(byte[ ] data, int length) //数据   数据长度
DatagramPacket  dp = DatagramPacket(byte[ ] data, int offset, int length)//数据  数据偏移量 数据长度
DatagramPacket  dp = DatagramPacket(byte[ ] data, int length, InetAddress remoteAddr, int remotePort)//数据  数据长度 目的ip地址 目的端口号  

方法
在这里插入图片描述

服务端给客户端发送消息(基于UDP协议的网络通信)

Server

public class Server {

	@SuppressWarnings("resource")
	public static void main(String[] args) throws SocketException, Exception {
		//创建套接字
		DatagramSocket ds = new DatagramSocket();
		//要发送的数据
		String str="你好,我是服务端";
		//创建要发送的数据报包,传入要发送的数据,数据长度,目的ip地址及端口号
		DatagramPacket datagramPacket = new DatagramPacket(str.getBytes(), str.length(),InetAddress.getByName("127.0.0.1"),7788);
		//发送数据
		ds.send(datagramPacket);
		//释放资源
		ds.close();
	}
}

Client

public class Client {

    @SuppressWarnings("resource")
	public static void main(String[] args) throws Exception {
		
    	//创建套接字,端口号7788
    	DatagramSocket ds = new DatagramSocket(7788);
        //创建DatagramPacket对象,用于接收数据
    	DatagramPacket dp = new DatagramPacket(new byte[1024], 1024);
    	//等待接收数据,没有数据则阻塞
    	ds.receive(dp);
    	
    	String str = new String(dp.getData(),0,dp.getLength());
	   //打印接收到的信息
        System.out.println(str+"来自"+dp.getAddress()+"-----"+dp.getPort());
       ds.close();
    }
}

效果图
在这里插入图片描述

服务端和客户端即时通信(UDP协议网络通信)

Server

public class Server {

	public static void main(String[] args) throws Exception {
		//创建发送套接字               
		DatagramSocket sendsocket = new DatagramSocket(10000);
		//创建接收套接字
		DatagramSocket recesocket = new DatagramSocket(9000);
		//准备目的主机的IP地址
		InetAddress address = InetAddress.getByName("localhost");
		//发送线程建立         发送套接字,目的主机IP地址和目的主机用于接收的端口号
		Send_Thread send_thread = new Send_Thread(sendsocket, address,8888);
		//接收线程的建立
		Receive_Thread rece_thread = new Receive_Thread(recesocket);
		//启动线程
		send_thread.start();
		rece_thread.start();

	}
}

Client

public class Client {

	public static void main(String[] args) throws Exception {
		
		//创建发送套接字
		DatagramSocket sendsocket = new DatagramSocket(10001);
		//创建接收套接字
		DatagramSocket recesocket = new DatagramSocket(8888);
		//准备目的主机的IP地址
		InetAddress address = InetAddress.getByName("localhost");
		//发送线程建立            //发送套接字,目的主机IP地址和目的主机用于接收的端口号
		Send_Thread send_thread = new Send_Thread(sendsocket, address,9000);
		//接收线程的建立
		Receive_Thread rece_thread = new Receive_Thread(recesocket);
		//启动线程
		send_thread.start();
		rece_thread.start();
	}

}

Send_Thread

public class Send_Thread extends Thread {
	//发送的socket端
    private DatagramSocket sender = null;
    //待发送的目标地址
    private InetAddress address = null;
    private int port;   //监听端口
    //从键盘输入
    Scanner scan = new Scanner(System.in);
    public Send_Thread(DatagramSocket sender,InetAddress address,int port)
    {
        this.sender = sender;
        this.address = address;
        this.port = port;
    }
    public void run(){
    	  try{
              while(true){
                  //输入待发送的内容
                  String input = scan.nextLine();
                  if(input.equals("exit"))
                      break;
                  byte[] data = null;
                  data = input.getBytes("UTF-8");
                  //构造数据报包对象
                  DatagramPacket pack = new DatagramPacket(data, data.length,address,port);
                  sender.send(pack);    
              }
              System.out.println("Exit!");  
          }catch(IOException e){
        	  
          }

    }

}

Receive_Thread

public class Receive_Thread extends Thread {
	private static final int MAX_RECEIVE_BUFFER = 1024;
    private DatagramSocket server;
    private DatagramPacket packet;
    byte[] buffer = new byte[MAX_RECEIVE_BUFFER];
    public Receive_Thread(DatagramSocket server){
        this.server = server;
        packet = new DatagramPacket(buffer, buffer.length);
    }
   
    public void run(){
    	   while(true) {
    	      //接收套接字负责接收数据包
    	      try {
				server.receive(packet);
				//数据报包中获取数组格式的数据转为字符串格式
	    	    String s = new String(packet.getData(),packet.getOffset(),packet.getLength(),"UTF-8");
	    	    System.out.println(packet.getAddress()+":端口号"+packet.getPort()+"说 :"+s);
	    	  
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
    	       }
    	}
}

效果图
在这里插入图片描述
在这里插入图片描述

UDP与TCP协议比较

优缺点比较
在这里插入图片描述
适用场景对比
TCP协议适用于对网络质量有要求的场景。比如文件传输,发送或接收邮件。
UDP协议适用于对网络通讯质量要求不高,但速度要快的场景。比如语音广播或视频。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值