2021-1-java.net.Socket

这篇博客介绍了如何实现基于Java的网络通信应用,包括你画我猜游戏和视频通话功能。服务器端通过Socket接收客户端的坐标数据,实时绘制线条。客户端利用图形接口监听鼠标事件,将绘制操作发送给服务器。同时,视频通话部分展示了如何通过数据流传输视频帧和绘制信息,实现两端的同步显示。整个系统运用了多线程和数据流处理,实现了基本的实时交互功能。
摘要由CSDN通过智能技术生成
你画我猜
  • 先构建服务器端:

    public class DrawServer {
    	int x1,x2,y1,y2;
       boolean setServer(int port){
    	   try {
    		   //打开指定端口的插座
    		   ServerSocket serverSocket = new ServerSocket(port);
    		System.out.println("服务器创建成功...");
    		Socket accept = serverSocket.accept();//卡在这里等
    		JFrame jf=new JFrame("你画我猜服务器端");
    		jf.setSize(800,800);
    		jf.setVisible(true);
    		Graphics graphics=jf.getGraphics();
    		InputStream inputStream = accept.getInputStream();
    		OutputStream outputStream = accept.getOutputStream();
    		//不断接收数据
    		while(true){
    		   DataInputStream dataInputStream=new DataInputStream(inputStream);
    		   x1 = dataInputStream.readInt();
    		   System.out.println("x1:"+x1);
    		   y1 = dataInputStream.readInt();
    		   System.out.println("x1:"+y1);
    		   x2 = dataInputStream.readInt();
    		   System.out.println("x1:"+x2);
    		   y2 = dataInputStream.readInt();
    		   System.out.println("x1:"+y2);
    			graphics.drawLine(x1, y1, x2, y2);
    		}
    	} catch (IOException e) {
    		// TODO Auto-generated catch block
    		e.printStackTrace();
    	}
    	return false; 
       }
       public static void main(String[] args) {
    DrawServer drawServer=new DrawServer();
    drawServer.setServer(9999);
    }
    }
    
    
    
  • 客户端(客户端采用界面和服务分开)

    public class DrawConn {
    	DataOutputStream dataOutputStream;
    	OutputStream out;
    	public void seendLine(int x1,int y1,int x2,int y2){
    		try {
    			//此处犯过错误,因为dataoutputstream不能先new
    			dataOutputStream=new DataOutputStream(out);
    			dataOutputStream.writeInt(x1);
    			System.out.println("客户端写入第一个数据"+x1);
    			dataOutputStream.writeInt(y1);
    			System.out.println("客户端写入第二个数据"+y1);
    			dataOutputStream.writeInt(x2);
    			System.out.println("客户端写入第三个数据"+x2);
    			dataOutputStream.writeInt(y2);
    			System.out.println("客户端写入第四个数据"+y2);
    			System.out.println("发送成功");
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			try {
    				dataOutputStream.close();
    			} catch (IOException e1) {
    				// TODO Auto-generated catch block
    				e1.printStackTrace();
    			}
    			e.printStackTrace();
    		}
    		
    	}
    	public boolean connetServer(){
    		  try {
    			Socket socket = new Socket("127.0.0.1",9999);
    			System.out.println("连接成功");
    			InputStream inputStream = socket.getInputStream();
    			out=socket.getOutputStream();
    			return true;
    		} catch (Exception e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    		return false; 
    		  
    	  }
    }
    
    
    • 客户端界面

      public class DrawUI extends JFrame{
      	DrawConn drawConn;
      	int x1,x2,y1,y2;
      	public static void main(String[] args) {
      		DrawUI drawUI = new DrawUI();
      		drawUI.showUI();
      	}
        public void showUI(){
      	  this.setSize(800,800);
      	  this.setTitle("网络客户端画图板");
      	 this.setVisible(true);
      	 this.setDefaultCloseOperation(3);
      	 drawConn=new DrawConn();
      	 if(drawConn.connetServer()){
      		 Graphics graphics=this.getGraphics();
      		 this.addMouseListener(new MouseAdapter() {
      			@Override
      			public void mouseReleased(MouseEvent e) {
      				// TODO Auto-generated method stub
      				x2=e.getX();
      				y2=e.getY();
      				graphics.drawLine(x1, y1, x2, y2);
      				System.out.println("客户端画了x1:"+x1+"y1:"+y1+"x2:"+x2+"y2:"+y2);
      			     //接下来要发送数据给客户端
      				drawConn.seendLine(x1, y1, x2, y2);	
      			}
      			@Override
      			public void mousePressed(MouseEvent e) {
      				// TODO Auto-generated method stub
      				x1=e.getX();
      				y1=e.getY();
      			}
      		});
      	 }
        }
      }
      
视频通话
  • 服务器端

    /**
     * @ClassName: VedioServer
     * @Description: TODO创建服务器并接受来自客户端的数据
     * @author TwoDaysZzz
     * @date 2021年1月22日
     * 
     */
    public class VedioServer {
    	int[][] vdeioa;
    	Graphics graphics;
      Socket acSocket=null;
      //线程池
      ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
    	/**
    	 * @param graphics获得服务器界面的画笔
    	 */
    	public VedioServer(Graphics graphics) {
    		this.graphics = graphics;
    	}
    
    	/**
    	 * @Title: setServer @Description: TODO打开服务器接收数据 @param port @return
    	 * void @throws
    	 */
    	public void setServer(int port) {
    		try {
    			ServerSocket serverSocket = new ServerSocket(port);
    			System.out.println("创建成功");
    			while(true){
    				Socket accept = serverSocket.accept();// 阻塞
    			   executorService.execute(new ServiceThreadTask(accept,graphics));
    			}
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    	}
    }
      class ServiceThreadTask  implements  Runnable{
    	  Socket acSocket;
    	  Graphics graphics;
    	  public ServiceThreadTask(Socket socket,Graphics graphics) {
          this.acSocket=socket;
          this.graphics =graphics;
    	  }
    	  public ServiceThreadTask() {
    	}
    	public void run() {
    		DataInputStream dataInputStream = null;
    		DataOutputStream dataOutputStream  = null;
    		try {
    			
    			dataInputStream = new DataInputStream(acSocket.getInputStream());
    			while(true){byte bytea = dataInputStream.readByte();
    			switch (bytea) {
    			case 1:
    				getVedioImage(dataInputStream);
    				break;
    			case 2:
    				getVediodraw(dataInputStream);
    				break;
    			default:
    				break;
    			}
    			}
    		}catch (Exception e){
    			
    		}
    	}
    	
    	/**
    	 * @Title: getVedioImage @Description: TODO获取数据流中视频RGB数组并显示 @param
    	 * dataInputStream @return void @throws
    	 */
    	public void getVedioImage(DataInputStream dataInputStream) {
    		try {
    			System.out.println("接收成功");
    			int w = dataInputStream.readInt();
    			int h = dataInputStream.readInt();
    			int[][] ia = new int[w][h];
    			
    			for (int i = 0; i < w; i++) {
    				for (int j = 0; j < h; j++) {
    					ia[i][j] = dataInputStream.readInt();
    					Color color = new Color(ia[i][j]);
    					graphics.setColor(color);
    					graphics.drawOval(i, j, 1, 1);
    				}
    			}
    			
    			
    			
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    	}
    	public void getVediodraw(DataInputStream dataInputStream) {
    		// x1,y1,x2,y2
    		try {
    		
    			int x1 = dataInputStream.readInt();
    			int y1 = dataInputStream.readInt();
    			int x2 = dataInputStream.readInt();
    			int y2 = dataInputStream.readInt();
    			graphics.drawLine(x1, y1, x2, y2);
               
    		
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    	}
    
    	
    }
    
    
  • 服务器端ui界面

    public class VedioServerUI extends JFrame{
    	
    	/**  
    	* @Title: initUI  
    	* @Description: TODO 设置服务器打开的断开,打开服务器  
    	* @return void 
    	* @throws  
    	*/  
    	public void   initUI(){
    		this.setSize(400,400);
    		this.setVisible(true);
    		this.setDefaultCloseOperation(3);
    		this.setTitle("服务器");
    		Graphics graphics = this.getGraphics();
    		 VedioServer vedioServer=new VedioServer(graphics);
    		 vedioServer.setServer(9999);
    	  }
    	/**  
    	* @Title: main  
    	* @Description: TODO打开服务器界面
    	* @param args    
    	* @return void 
    	* @throws  
    	*/  
    	public static void main(String[] args) {
    		VedioServerUI vedioServerUI=new VedioServerUI();
    		vedioServerUI.initUI();
    	}
    }
    
    
  • 客户端服务

    /**  
    * @ClassName: VedioConn  
    * @Description: TODO打开端口,传输数据!!!
    * @author TwoDaysZzz 
    * @date 2021年1月22日  
    */  
    public class VedioConn {
    	DataOutputStream dataOutputStream;
    	   /**  
    	* @Title: conn  
    	* @Description: TODO打开端口,用来传输数据
    	* @return    
    	* @return boolean 如果连接上了,返回true,否则不能进行下一步
    	* @throws  
    	*/  
    	public boolean conn(){
    		    try {
    		    	Socket socket = new Socket("127.0.0.1",9999);
    		    	System.out.println("连接成功");
    			    InputStream inputStream = socket.getInputStream();
    			    OutputStream outputStream = socket.getOutputStream();
    			    dataOutputStream=new DataOutputStream(outputStream);
    			    // inputStream.close();
    		    	//outputStream.close();
    			    return true;
    		    } catch (Exception e) {
    		    	
    				// TODO Auto-generated catch block
    		    	
    				e.printStackTrace();
    			} 
    		return false;   
    	   }
    	/**  
    	* @Title: sendVedio  
    	* @Description: TODO发送视频数据
    	* @param vedioa    
    	* @return void 
    	* @throws  
    	*/  
    	public synchronized  void  sendVedio(BufferedImage image){
    		try {
    			//先发送字节1标识发出的数据是视频数据
    			dataOutputStream.writeByte(1);
    		
    				// TODO Auto-generated method stub
    				int [][]ia;
    				int w=image.getWidth();
    				int h=image.getHeight();
    				ia=new int[w][h];
    				dataOutputStream.writeInt(w);
    				dataOutputStream.writeInt(h);
    				for(int i=0;i<w;i++){
    					for(int j=0;j<h;j++){
    						dataOutputStream.writeInt(image.getRGB(i, j));
    					}
    				}			
    			dataOutputStream.flush();
    			//dataOutputStream.close();
    	
    		}catch (IOException e) {
    			// TODO Auto-generated catch block
    			try {
    				dataOutputStream.close();
    			} catch (IOException e1) {
    				// TODO Auto-generated catch block
    				e1.printStackTrace();
    			}
    			System.out.println("发送失败");
    			e.printStackTrace();
    		}
    		
    	}
    	/**
    	 * @return   
    	* @Title: sendLine  
    	* @Description: TODO传输涂鸦笔的坐标
    	* @param x1
    	* @param y1
    	* @param x2
    	* @param y2    
    	* @return void 
    	* @throws  
    	*/  
    	public  synchronized  void sendLine(int x1,int y1,int x2,int y2){
    	    	try {
    
    				dataOutputStream.writeByte(2);
    			    dataOutputStream.writeInt(x1);
    			    dataOutputStream.writeInt(y1); 
    			    dataOutputStream.writeInt(x2); 
    			    dataOutputStream.writeInt(y2);
    			    dataOutputStream.flush();
    	    	} catch (IOException e) {
    				// TODO Auto-generated catch block
    	    		try {
    					dataOutputStream.close();
    				} catch (IOException e1) {
    					// TODO Auto-generated catch block
    					e1.printStackTrace();
    				}
    				e.printStackTrace();
    			}
    	}
    }
    
    
  • 客户端ui

    /**  
    * @ClassName: VideoClientUI  
    * @Description: TODO打开摄像头,主界面显示
    * @author TwoDaysZzz 
    * @date 2021年1月22日  
    *    
    */  
    public class VideoClientUI extends JFrame{
    	
    	
    	/**  
    	* @Title: main  
    	* @Description: TODO打开客户端主界面
    	* @param args    
    	* @return void 
    	* @throws  
    	*/  
    	public static void main(String[] args) {
    		
    		VideoClientUI videoClientUI=new VideoClientUI();
    		videoClientUI.init();
    	}
    	int x1,y1,x2,y2;
    	int count=0;
    
    
    /**  
    * @Title: init  
    * @Description: TODO设置客户端界面,打开摄像头,通过端口发送数据 。
    * @return void 
    * @throws  
    */  
    public void init(){
    	  this.setSize(400,400);
    	  this.setTitle("客户端meeting");
    	  this.setVisible(true);
    	  this.setDefaultCloseOperation(3);
    	  Graphics graphics=this.getGraphics();
    	  VedioConn vedioConn =new VedioConn();
    	  JframListener jframListener=new JframListener(graphics,vedioConn);
    	  this.addMouseListener(jframListener);
    		  if( vedioConn.conn()){
    			   Webcam webcam=Webcam.getDefault();
    	           webcam.open();
    
    			  //发送数据 
    	  while(true){
    		  BufferedImage image= webcam.getImage();
    		  //int [][] ia=toArray(image);
    		graphics.drawImage(image, 100, 100, null) ;
    		 vedioConn.sendVedio(image);
    	    // vedioConn.sendLine(x1, y1, x2, y2);
    	  }
    		  }  
      }
    /**  
    * @Title: toArray  
    * @Description: TODO将视频得到的image转为RGB数组,以便通过数据流传输
    * @param image
    * @return    
    * @return int[][] 
    * @throws  
    */  
    private int[][] toArray(BufferedImage image) {
    	// TODO Auto-generated method stub
    	int [][]ia;
    	int w=image.getWidth();
    	int h=image.getHeight();
    	ia=new int[w][h];
    	for(int i=0;i<w;i++){
    		for(int j=0;j<h;j++){
    			int rgb = image.getRGB(i, j);
    			ia[i][j]=rgb;
    		}
    	}
    	
    	return ia;
    }
    }
    /**  
    * @ClassName: JframListener  
    * @Description: TODO鼠标监听客户端的涂鸦笔
    * @author TwoDaysZzz 
    * @date 2021年1月22日  
    *    
    */  
    class JframListener implements MouseListener{
    	
    	VedioConn conn;
    	Graphics graphics;
    	int x1,y1,x2,y2;
    	
      public JframListener(Graphics graphics,VedioConn conn) {
    	// TODO Auto-generated constructor stub
    	  this.conn=conn;
    	  this.graphics=graphics;
    }
    	  
    		public void mousePressed(MouseEvent e) {
    	    	x1=e.getX();
    	    	y1=e.getY();
    	    }
    
    	    /**
    	     * {@inheritDoc}
    	     */
    	    public void mouseReleased(MouseEvent e) {
    	    	
    	    	x2=e.getX();
    	    	y2=e.getY();
    	    	graphics.drawLine(x1, y1, x2, y2);
    	    	conn.sendLine(x1, y1, x2, y2);
    	    }
    		@Override
    		public void mouseClicked(MouseEvent e) {
    			// TODO Auto-generated method stub
    			
    		}
    		@Override
    		public void mouseEntered(MouseEvent e) {
    			// TODO Auto-generated method stub
    			
    		}
    		@Override
    		public void mouseExited(MouseEvent e) {
    			// TODO Auto-generated method stub
    			
    		}
    
    }
    
简易聊天
  • 服务器端ui+服务
public class QqServer {
	JTextArea jTextArea;
	DataInputStream dataInputStream;
	DataOutputStream dataOutputStream;
	  ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
	  boolean setServer(int port){
    	JFrame jFrame=new JFrame("服务端");
	    jFrame.setSize(400,300);
	    JButton jButton=new JButton("Send");
	    jFrame.add(jButton);
	  //给发送按钮加监听器
	    JTextField jTextField =new JTextField(20);
	    jFrame.add(jTextField);
	    JTextArea jTextArea =new JTextArea(10,30);
	    jFrame.add(jTextArea);
	    jFrame.setLayout(new FlowLayout());
	    jFrame.setVisible(true);
	    jFrame.setDefaultCloseOperation(3);
	    
	    //给按钮添加监听器
	    jButton.addActionListener(new ActionListener() { 	
  			public void actionPerformed(ActionEvent e) {
  			 //1.取得输入框输入的内容
  				String string=jTextField.getText();
  			//	System.out.println("服务器发送: "+string);
  			//调用网络模块发送,是发给所有的客户机对象了
  				CastAll.castMSGtoAll(string);;//static  不是没用,是一定要用到,才有用
   				jTextField.setText(""); //清空
   				//System.out.println("发送成功");
  			}
  		});
    	try {
			ServerSocket serverSocket = new ServerSocket(port);
			System.out.println("创建成功");
			while(true){
				/*
				 * 为accept开启一个线程
				 * */
				Socket accept = serverSocket.accept();// 阻塞
				ServiceThreadTask serviceThreadTask=new ServiceThreadTask(accept,jTextArea,executorService);
				//记录socket
				CastAll.serviceThreadTasks.add(serviceThreadTask);
			   executorService.execute(serviceThreadTask);
			   
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    	
		return false;
    	
    }
    public static void main(String[] args) {
		QqServer qsQqServer=new QqServer();
		qsQqServer.setServer(9999);
	}
}

class ServiceThreadTask  implements  Runnable{
	  Socket acSocket;
	  JTextArea jTextArea;
	  ExecutorService executorService;
	  public ServiceThreadTask(Socket socket,JTextArea jTextArea,ExecutorService executorService) {
    this.acSocket=socket;
    this.jTextArea =jTextArea;
    this.executorService=executorService;
	  }
	  public ServiceThreadTask() {
	}
	public void run() {
		DataInputStream dataInputStream = null;
	//	DataOutputStream dataOutputStream  = null;
		try {
			dataInputStream = new DataInputStream(acSocket.getInputStream());
		  
			String string ="欢迎连接,这是服务器一号";
			while(true){ 
				byte type=dataInputStream.readByte();
			//byte bytea = dataInputStream.readByte();
			switch (type) {
			case 1:
			//	getVedioImage(dataInputStream);
				break;
			case 2:
				//getVediodraw(dataInputStream);
				break;
			case 3:
			//sendMsgtoClient();
				int len =dataInputStream.readInt();
				byte [] bytes=new byte[len];
				
				 dataInputStream.read(bytes);
				String readMsg=new String(bytes);
				jTextArea.append("客户端:"+readMsg+"\n");
				
				CastAll.castMSGtoAll(string);
				System.out.println("服务器接收:"+readMsg);
				break;
			default:
				break;
			}
			}
		}catch (Exception e){
			
		}
	}
public  void sendMsgtoClient(String string){
	
	DataOutputStream dataOutputStream=null;
	try {
		dataOutputStream=new DataOutputStream(acSocket.getOutputStream());
		byte[] bytes =string.getBytes();
		int len =bytes.length;
		dataOutputStream.writeByte(3);
		dataOutputStream.writeInt(len);
		dataOutputStream.write(bytes);
		dataOutputStream.flush();
		jTextArea.append("服务器:"+string+"\n");
		System.out.println("服务器:"+string);
	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	
	
	}
	
}

  • 客户端服务

    /**  
    * @ClassName: QqClientConn  
    * @Description: TODO子线程用来处理与服务器的通信
    * @author TwoDaysZzz 
    * @date 2021年1月24日  
    */  
    public class QqClientConn  extends Thread{
    	Socket socket;
    	JTextArea jt;
    	InputStream inputStream=null;
    	OutputStream outputStream=null;
    	public QqClientConn(JTextArea
    			jTextArea) {
    		// TODO Auto-generated constructor stub
    		this.jt=jTextArea;
    	}
       boolean conn(){
    	   try {
    		socket = new Socket("127.0.0.1",9999);
    		inputStream =socket.getInputStream();
    		outputStream=socket.getOutputStream();
    		return true;		
    	} catch (Exception e) {
    		// TODO Auto-generated catch block
    		e.printStackTrace();
    	} 
    	return false;
    	   
       }
    
       /**  
    * @Title: sendMsg  
    * @Description: TODO用来发送
    * @param mString    
    * @return void 
    * @throws  
    */  
    void sendMsg(String mString){
    	DataOutputStream dataOutputStream=null;
    	   try {
    		   dataOutputStream=new DataOutputStream(outputStream);
    		dataOutputStream.writeByte(3);
    		byte [] data =mString.getBytes();
    		int len =data.length;
    		dataOutputStream.writeInt(len);
    		dataOutputStream.write(data);
    		jt.append("我:"+mString+"\n");
    		dataOutputStream.flush();
    		System.out.println("客户机发送"+mString);
    	} catch (IOException e) {
    		// TODO Auto-generated catch block
    		e.printStackTrace();
    	} 
       }
    /**  
    * @Title: run  
    * @Description: TODO用来读取消息
    * @throws  
    */  
    public void run() {
    	// TODO Auto-generated method stub
    	DataInputStream dataInputStream=null;
    	try {
    		dataInputStream=new DataInputStream(inputStream);
    		while(true){
    			System.out.println("222222222222222222");
    		byte readByte = dataInputStream.readByte();
    		if(readByte==3){
    			//发送信息的长度
    			int len =dataInputStream.readInt();
    			byte []data=new byte[len];
    			dataInputStream.read(data);
    			String string=new String(data);
    			
    			this.jt.append("服务器:"+string+"\n");
    			System.out.println("客户端接收到了"+string);
    		}
    		}
    	} catch (Exception e) {
    		// TODO Auto-generated catch block
    		e.printStackTrace();
    	}
    }
    }
    
    
  • 客户端ui

    public class QqClientUi extends JFrame {
    	public void initUI() {
    		this.setSize(400, 300);
    		this.setTitle("QQ客户端");
    		JButton buSend = new JButton("Send");
    		this.add(buSend);
    		final JTextField jtfField = new JTextField(20);
    		this.add(jtfField);
    		// 接收显示:多行文本框
    		javax.swing.JTextArea jta = new javax.swing.JTextArea(10, 30);
    		this.add(jta);
    
    		this.setLayout(new FlowLayout());
    		this.setDefaultCloseOperation(3);
    		this.setVisible(true);
    		// 创建连结器对象,也是一读的线程对象
    		final QqClientConn qqClientConn = new QqClientConn(jta);
    		if (!qqClientConn.conn()) {// 如果连结成功,才做后面的
    			return;
    		}
    		qqClientConn.start();
    		// 说明连结成功了。。。。。。。
    		// 启动接收线程
    		// 给发送按钮加监听器
    		buSend.addActionListener(new ActionListener() {
    			public void actionPerformed(ActionEvent e) {
    				// 1.取得输入框输入的内容
    				String inMsg = jtfField.getText();
    				// System.out.println("客户机己发送: "+inMsg);
    				// 调用网络模块发送
    				qqClientConn.sendMsg(inMsg);
    				jtfField.setText(""); // 清空
    			}
    		});
    	}
    	public static void main(String[] args) {
    		QqClientUi qqClientUi = new QqClientUi();
    		qqClientUi.initUI();
    	}
    }
    
    

    所有的代码都好乱好乱,不想改了嘤嘤嘤

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值