zoukankan      html  css  js  c++  java
  • JavaTCP和UDP套接字编程

    原文地址:http://www.cnblogs.com/MindMrWang/p/8919890.html
    在我们刚开始入门Java后端的时候可能你会觉得有点复杂,包含了很多杂七杂八的知识,例如文件上传下载,监听器,JDBC,请求重定向,请求转发等等(当然也没有很多),但是我们自己真正的去开发一个小型网站(对安全性一起其他并发不作要求)的时候,其实我们会发现,Java后端是真的省事,好像除了CURD还是CURD,没有什么更新鲜的了。但是我们回顾计算机网络的知识提出疑问,计算机信息传输有TCP和UDP两种连接方式,但是我们编程的时候怎么没体现?怎么回事呢?

    我们学JavaWeb的时候估计最熟悉的就是Servlet了,但是追下去其实我们写的后端Servlet只是实现了一个接口,并没有在里面实现什么方法,且刚开始编程的时候,总会到Tomcat文件夹下复制一个Jar包到项目中,我们的项目才可以运行,否则会报错是不是,所以我们大概可以推测出对于一些网络连接和传输都是Tomcat帮我们做了,也就是服务器帮我们做了,那么我们在实际的编码中怎么通过Java来实现计算机之间的通信呢?
    Java也为我们考虑到了,Java的网络编程,也叫作Socket编程!

    在了解网络编程之前,我们先了解一下什么叫套接字,套接字即指同一台主机内应用层和运输层之间的接口,由于这个套接字是建立在网络上建立网络应用的可编程接口,因此也将套接字称为应用程序和网络之间的应用程序编程接口!
    这里写图片描述

    关于TCP和UDP这里就不作太多介绍了,我们知道TCP是面向连接的,UDP是不面向连接的,TCP可靠,UDP不可靠即可!
    我们来设计一个应用来示范一下,流程:

    1. 客户机从键盘读取一行字符串,并通过套接字发送到服务器。
    2. 服务器从连接的套接字获取这行字符串,并对其进行修改(将小写转为大写),最后再发回客户端。
    3. 客户机读取到服务器发送的修改后的字符串,并输出到屏幕。

    不说太多了,直接上代码:

    TCPClient:

    public class TCPClient {
    	public static void main(String[] args) throws Exception {
    		//创建两个String类型的字符串用来发送和接受
    		String sentence;
    		String modifiedSentence;
    		
    		//创建输入流,用来接受键盘输入
    		BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
    		
    		//创建一个Socket类型的 clientSocket 用来发起服务器和客户机之间的连接
    		Socket clientSocket = new Socket("hostname",6789);
    		
    		//创建向服务器发送信息的输出流
    		DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
    		
    		//创建输入流,用来接收来自服务器的字节流
    		BufferedReader inFormServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
    		
    		//读流数据
    		sentence = inFromUser.readLine();
    		
    		//向服务器发送sentence的字节数据
    		outToServer.writeBytes(sentence + '
    ');
    		
    		//获取字节流数据为String
    		modifiedSentence = inFormServer.readLine();
    		
    		System.out.println("Form Server :" + modifiedSentence);
    	}
    }
    

    TCPServer:

    public class TCPServer {
    	public static void main(String[] args) throws Exception{
    		String clientSentence;
    		String capitalizedSentence;
    		
    		//服务器Socket用来建立连接
    		ServerSocket welcomeSocket = new ServerSocket(6789);
    		
    		while(true){
    			
    			//用这个连接来获取和发送,自客户端发的数据流
    			Socket connectionSocket = welcomeSocket.accept();
    			
    			//获取来自客户端的字节流
    			BufferedReader inFromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
    			
    			//发送更改后的数据流
    			DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream());
    			
    			//读取字节成String字符串
    			clientSentence = inFromClient.readLine();
    			
    			capitalizedSentence = clientSentence.toUpperCase() +'
    ';
    			
    			outToClient.writeBytes(capitalizedSentence);
    		}	
    	}
    }
    

    public class UDPClient {
    	public static void main(String[] args) throws Exception{
    		//读取键盘输入的字节流
    		BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
    		
    		//为客户机创建了一个传输信息的门,但是并没与向TCP那样建立连接
    		DatagramSocket clientSocket = new DatagramSocket();
    		
    		//这行代码调用了DNS查询,查询主机名对应的IP地址,后面要用这个地址来向服务器发送信息
    		InetAddress IPAddress = InetAddress.getByName("hostname");
    		
    		//需要发送的字节数组
    		byte[] sendData = new byte[1024];
    		
    		//接受的字节数组
    		byte[] receiveData = new byte[1024];
    		
    		String sentence = inFromUser.readLine();
    		
    		//将字符串转为字节放入sendData
    		sendData = sentence.getBytes();
    		
    		//UDP数据报分组,里面包含想要发送的内容以及目的地址等信息
    		DatagramPacket sendPacket = new DatagramPacket(sendData,sendData.length,IPAddress,9876);
    		
    		//用这个‘门’来发送这个数据包
    		clientSocket.send(sendPacket);
    		
    		//获取数据报分组
    		DatagramPacket receivePacket = new DatagramPacket(receiveData,receiveData.length);
    		
    		//用‘门’获取数据报
    		clientSocket.receive(receivePacket);
    		
    		//将获取的数据报转为String类型数据
    		String modifiedSentence = new String(receivePacket.getData());
    		
    		System.out.println("From Server:" + modifiedSentence);
    		
    		//关闭这个门
    		clientSocket.close();
    		
    	}
    }
    
    public class UDPServer {
    	public static void main(String[] args) throws Exception{
    		
    		//大意和客户端代码类似
    		DatagramSocket serverSocket = new DatagramSocket(9876);
    		
    		byte[] receiveData = new byte[1024];
    		
    		byte[] sendData = new byte[1024];
    		
    		while(true){
    			
    			DatagramPacket receivePacket = new DatagramPacket(receiveData,receiveData.length);
    			
    			serverSocket.receive(receivePacket);
    			
    			String sentence = new String(receivePacket.getData());
    			
    			InetAddress IPAddress = receivePacket.getAddress();
    			
    			int port = receivePacket.getPort();
    			
    			String capitalized = sentence.toUpperCase();
    			
    			sendData = capitalized.getBytes();
    			
    			DatagramPacket sendPacket = new DatagramPacket(sendData,sendData.length,IPAddress,port);
    			
    			serverSocket.send(sendPacket);
    		}
    	}
    }
    

    有网络基本常识的朋友应该很好理解上面的代码(记录供以后参考),博主在代码中也作了很详细的注释,这里就不在多解释什么了,相信通过上面简单的例子,我们能够了解Java是如何实现TCP和UDP套接字编程。

    以上代码参考《计算机网络自顶向下方法》,其他为博主的一些粗陋的见解,可能有不全面的地方,如果大神见到,还请赐教!

    参考书籍:《计算机网络自顶向下方法》

  • 相关阅读:
    【Codechef】Chef and Bike(二维多项式插值)
    USACO 完结的一些感想
    USACO 6.5 Checker Challenge
    USACO 6.5 The Clocks
    USACO 6.5 Betsy's Tour (插头dp)
    USACO 6.5 Closed Fences
    USACO 6.4 Electric Fences
    USACO 6.5 All Latin Squares
    USACO 6.4 The Primes
    USACO 6.4 Wisconsin Squares
  • 原文地址:https://www.cnblogs.com/MindMrWang/p/8919890.html
Copyright © 2011-2022 走看看