原文地址: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套接字编程。

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

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

JavaTCP和UDP套接字编程的更多相关文章

  1. 探索UDP套接字编程

    UDP和TCP处于同一层网络模型中,也就是运输层,基于二者之上的应用有很多,常见的基于TCP的有HTTP.Telnet等,基于UDP有DNS.NFS.SNMP等.UDP是无连接,不可靠的数据协议服务, ...

  2. 【Python网络编程】利用Python进行TCP、UDP套接字编程

    之前实现了Java版本的TCP和UDP套接字编程的例子,于是决定结合Python的学习做一个Python版本的套接字编程实验. 流程如下: 1.一台客户机从其标准输入(键盘)读入一行字符,并通过其套接 ...

  3. 【转】 探索UDP套接字编程

    UDP和TCP处于同一层网络模型中,也就是运输层,基于二者之上的应用有很多,常见的基于TCP的有HTTP.Telnet等,基于UDP有DNS.NFS.SNMP等.UDP是无连接,不可靠的数据协议服务, ...

  4. 计算机网络实验 UDP套接字编程

    这是个傻瓜式操作教程 西科大计算机网络实验 UDP套接字编程 我用自己的Ubuntu16.04来举例,实验室的是虚拟机,差不多 只针对第三个题目,修改服务器来通过响应客户端发送的GetTime并发送给 ...

  5. UDP套接字编程 返回系统时间

    计算机网络实验 简单UDP套接字编程 这是学校老师自己改进了一点的题目.我预习了好久才搞明白,同学来问的时候,一大堆简单问题实在是不想回答...所以,这时候我觉得博客是个好东西! 我的任务是做客户端和 ...

  6. 【Unix网络编程】chapter8基本UDP套接字编程

    chapter8基本UDP套接字编程 8.1 概述 典型的UDP客户端/服务端的函数调用 8.2 recvfrom和sendto函数 #include <sys/socket.h> ssi ...

  7. TCP和UDP套接字编程 (java实现)

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

  8. 《Unix 网络编程》08:基本UDP套接字编程

    基本UDP套接字编程 系列文章导航:<Unix 网络编程>笔记 UDP 概述 流程图 recvfrom 和 sendto #include <sys/socket.h> ssi ...

  9. java基础----->TCP和UDP套接字编程

    这里简单的总结一下TCP和UDP编程的写法,另外涉及到HttpUrlConnection的用法 . TCP套接字 一.项目的流程如下说明: .客户输入一行字符,通过其套接字发送到服务器. .服务器从其 ...

随机推荐

  1. EXT3文件系统误删除导致文件系统中的邮件丢失恢复方法

    一.故障描述 由8块盘组成的RAID5, 上层是EXT3文件系统,由于误删除导致文件系统中的邮件丢失 二.镜像磁盘为防止数据恢复过程中由于误操作对原始磁盘造成二次破坏, 使用winhex软件为每块磁盘 ...

  2. Spring+Hibernate+Struts(SSH)框架整合

    SSH框架整合 前言:有人说,现在还是流行主流框架,SSM都出来很久了,更不要说SSH.我不以为然.现在许多公司所用的老项目还是ssh,如果改成流行框架,需要成本.比如金融IT这一块,数据库dao层还 ...

  3. 延迟确认和Nagle算法

    前篇文章介绍了三次握手和四次挥手,了解了TCP是如何建立和断开连接的,文末还提到了抓包挥手时的一个“异常”现象,当时无法解释,特地查了资料,知道了数据传输中的延迟确认策略. 何谓延迟确认策略? WIK ...

  4. Spring Boot整合Spring Security

    Spring Boot对于该家族的框架支持良好,但是当中本人作为小白配置还是有一点点的小问题,这里分享一下.这个项目是使用之前发布的Spring Boot会员管理系统重新改装,将之前filter登录验 ...

  5. Autofac 简单示例

    公司不用任何IOC,ORM框架,只好自己没事学学. 可能有些语言描述的不专业 希望能有点用 namespace Autofac { class Program { //声明一个容器 private s ...

  6. Mybatis和Hibernate本质区别和应用场景

    Hibernate:是一个标准ORM(对象关系映射)框架.入门门槛较高,不需要程序员写sql语句,sql语句自动生成,对sql语句优化.修改比较困难 应用场景:适用于需求变化不多的中小型项目,比如后台 ...

  7. c++中模板是什么?为什么要定义模板?

    一.c++中模板是什么? 首先: int Max(int x, int y) { return x > y ? x : y; } float Max(float a,float b) { ret ...

  8. fetch简明学习

    前面的话 Fetch API 提供了一个 JavaScript接口,用于访问和操纵HTTP管道的部分,例如请求和响应.它还提供了一个全局 fetch()方法,该方法提供了一种简单,合乎逻辑的方式来跨网 ...

  9. Python 爬虫基础知识

    requests Python标准库中提供了:urllib.urllib2.httplib等模块以供Http请求,但是,它的 API 太渣了.它是为另一个时代.另一个互联网所创建的.它需要巨量的工作, ...

  10. Oracle12c:自动分区表

    为什么要创建oracle分区表? 一般情况下,如果不分区,则每次查询的对象都是一整张表,如果采用了表分区,那么可以根据具体的分区字段当作条件来避免扫描整张表,减少IO的扫描以提高表的查询速度. 新建( ...