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 + '\n');
        
        //获取字节流数据为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() +'\n';
            
            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套接字编程。

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

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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Pythonista

牛掰的python与unix

  加载subprocess模块仅仅是将可以使用的代码文件加载进来。也可以创建自己的模块或文件,拱以后重复使用,这与加载subprocess模块的方法相同。IP...

1052
来自专栏Android开发指南

2.下拉刷新、二维码

3447
来自专栏子勰随笔

URL编码中的空格(编码以后变为+)

24210
来自专栏SDNLAB

源码解读ODL的MAC地址学习(一)

1 简介 我们知道同一子网中主机之间互相传送信息需要用到MAC地址,而我们第一次发送信息的时候只有IP地址而没有MAC地址,所以我们就要进行MAC地址自学习。 ...

7426
来自专栏JetpropelledSnake

SNMP学习笔记之SNMP报文协议详解

简单网络管理协议(SNMP)是TCP/IP协议簇的一个应用层协议。在1988年被制定,并被Internet体系结构委员会(IAB)采纳作为一个短期的网络管理解决...

1132
来自专栏Golang语言社区

用Go实现一门解释型语言

A interpreter language implementation in Go

852
来自专栏学海无涯

Java Web之Servlet获取表单值

Java Web开发中,最常用的就是在后台获取前台的参数,经典的案例就是 JSP 表单传值到后台的 Servlet,然后在 doGet 或者 doPost 中获...

3234
来自专栏JackieZheng

探秘Tomcat——启动篇

tomcat作为一款web服务器本身很复杂,代码量也很大,但是模块化很强,最核心的模块还是连接器Connector和容器Container。具体请看下图: ? ...

4587
来自专栏Java学习之路

JavaTCP和UDP套接字编程

原文地址:http://www.cnblogs.com/MindMrWang/p/8919890.html 在我们刚开始入门Java后端的时候可能你会觉得有点...

3325
来自专栏代码散人

Vapor奇幻之旅(04Routing)

Vapor的Routing提供了RouteBuilder和RouteCollection

792

扫码关注云+社区