标签:步骤 适合 因此 管理 host ntc network close address
1 TCP和UDP介绍
在介绍TCP和UDP之前,有必要先介绍下网络体系结构的各个层次。
1.1 网络体系结构
协议:控制网络中信息的发送和接收。定义了通信实体之间交换报文的格式和次序,以及在报文传输或接收或其他事件所采取的动作。
一般把网络的层次结构和每层所使用协议的集合称为网络体系结构(NetworkArchitecture)。
由国际标准化组织ISO 在1981年提出的网络分层结构,简称为OSI参考模型。(Open Systems Interconnection Reference Model)。
各层协议如下,可以看出TCP和UDP协议在传输层。
各层功能
1)链路层
链路层的功能:是把接收到的网络层数据报(也 称IP数据报)通过该层的物理接口发送到传输介质上,或从物理网络上接收数据帧,抽出IP数据报并交给IP层。
链路层通常包括操作系统中的设备驱动程序和计算机中对应的网络接口卡。
2)网络层
主要功能:是可以把源主机上的分组发送到互联网中的任何一台目标主机上。
3)传输层
为运行在不同主机上的应用进程提供逻辑通信功能(主机好像是直接相连的)。
进程之间使用逻辑通信功能彼此发送报文,无需考虑具体物理链路。
传输层主要包括种协议:传输控制协议(TCP),用户数据报协议(UDP)。
4)应用层
应用层向使用网络的用户提供特定的、常用的应用程序。
表示层:通信用户之间数据格式的转换、数据压缩及加解密等。
会话层:对数据传输进行管理,包括数据交换的定界、同步,建立检查点等。
1.2 套接字
套接字是从网络向进程传递数据,或从进程向网络传递数据的门户。传输层和应用层的进程通过套接字来传递数据。
主机上的套接字可以有多个,每个套接字都有惟一的标识符(格式取决于UDP或TCP)。
当报文段到达主机时,运输层检查报文段中的目的端口号,将其定向到相应的套接字。
1.3 用户数据报协议UDP
用户数据报协议UDP(User Datagram Protocol):提供用户之间的不可靠、无连接的报文传输服。使用UDP协议的原因
1)无连接创建(减少时延)
2)简单:无连接(在UDP发送方和接收方之间无握手)
3)段首部小
4)无拥塞控制: UDP能够尽可能快地传输
经UDP的可靠传输 : 在应用层增加可靠性,实现特定的差错恢复!
1.4 传输控制协议TCP
传输控制协议TCP(Transmission Control Protocol):提供用户之间可靠的、面向连接的报文传输服务。
面向连接、可靠的服务是指在进行数据交换前,初始化发送方与接收方状态,进行握手(交换控制信息)。
建立一个TCP 连接的作用:让发送方和接收方都做好准备,准备好之后就要开始进行数据传输了。三次握手建立TCP连接
三次握手的目的主要在于同步连接双方发送数据的初始序列号。
TCP 连接是一种全双工的连接,即一个TCP 连接的两个端点之间可以同时发送和接收数据,而不是每一个时刻只能有一个端点发送数据。
1.5 TCP与UDP的比较
TCP与UDP特点比较
TCP 是一种面向连接的协议,而UDP 是无连接的协议。
TCP 提供的是可靠的传输服务,而UDP 协议提供的是不可靠的服务。
TCP 提供的是面向字节流的服务。
UDP 协议的传输单位是数据块,一个数据块只能封装在一个UDP 数据包中。
解释:
1)可靠、连接
UDP不可靠、无连接:在UDP发送方和接收方之间无握手(交换控制信息)。
面向连接举例:两个人之间通过电话进行通信;
面向无连接举例:邮政服务,用户把信函放在邮件中期待邮政处理流程来传递邮政包裹。显然,不可达代表不可靠。
2)TCP面向字节流和UDP面向数据块(面向报文)
面向报文的传输方式是应用层交给UDP多长的报文,UDP就照样发送,即一次发送一个报文。因此,应用程序必须选择合适大小的报文。若报文太长,则IP层需要分片,降低效率。若太短,会使IP太小。UDP对应用层交下来的报文,既不合并,也不拆分,而是保留这些报文的边界。这也就是说,应用层交给UDP多长的报文,UDP就照样发送,即一次发送一个报文。
面向字节流的话,虽然应用程序和TCP的交互是一次一个数据块(大小不等),但TCP把应用程序看成是一连串的无结构的字节流。TCP有一个缓冲,当应用程序传送的数据块太长,TCP就可以把它划分短一些再传送。如果应用程序一次只发送一个字节,TCP也可以等待积累有足够多的字节后再构成报文段发送出去。
TCP 协议与UDP协议应用的比较
TCP 协议对于有大量数据需要进行可靠传输的应用是很适合的。比如可用于文件传输协议(FTP )。
对于虽然数据量少但需要时间较长且可靠性要求高的应用TCP 也是比较适合的。 Telnet 就是这种应用的一个例子。
实时应用适合使用UDP 协议。
对于多个实体间的多播式应用无法使用TCP 进行通信 。
从程序实现的角度,TCP与UDP的过程如下
从上图也能清晰的看出,TCP通信需要服务器端侦听listen、接收客户端连接请求accept,等待客户端connect建立连接后才能进行数据包的收发(recv/send)工作。而UDP则服务器和客户端的概念不明显,服务器端即接收端需要绑定端口,等待客户端的数据的到来。后续便可以进行数据的收发(recvfrom/sendto)工作。
2 JAVA代码
在JAVA中TCP套接字由Socket类实现,UDP套接字由DatagramSocket类实现。
2.1 TCP的JAVA代码大致如下
TCP网络编程步骤
1)创建Socket
2)打开连接到socket的输入、输出流
3)按照一定的协议对socket进行读、写操作(接收消息-处理数据-发送消息)
4)关闭socket
服务端代码
- <span style="font-size:14px;"> public static start(){
- ServerSocket serverSocket=null;
- try {
- int i=1;
-
-
- int maxConnection="10";
- serverSocket = new java.net.ServerSocket(8189,maxConnection);
-
-
- Socket sct=serverSocket.accept();
-
-
- InputStream inStream = clientSocket.getInputStream();
- BufferedReader in = new BufferedReader(new InputStreamReader(inStream));
-
- OutputStream outStream = clientSocket.getOutputStream();
- BufferedWriter out = new BufferedWriter(new OutputStreamWriter(outStream));
-
-
-
- String response="",lineStr = in.readLine();
- while(lineStr!=null){
- response += lineStr;
- lineStr = in.readLine();
- }
-
-
-
-
- out.wirte("TODO");
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
- finally{
- if(serverSocket!=null)
- serverSocket.close();
- }
- }
客户端代码与服务端代码类似,只不过服务端对客户端的请求是accept,而客户端需要连接服务端,所以使用connect方法,如下
- <span style="font-size:14px;"> public static start(){
- ServerSocket serverSocket=null;
- try {
- int i=1;
-
-
- Socket clientSocket = new Socket(String serverMachineIp, int port);
- int timeout=1000;
- clientSocket.connect(sa, timeout);
-
-
- InputStream inStream = clientSocket.getInputStream();
- BufferedReader in = new BufferedReader(new InputStreamReader(inStream));
-
- OutputStream outStream = clientSocket.getOutputStream();
- BufferedWriter out = new BufferedWriter(new OutputStreamWriter(outStream));
-
-
- /向客户端发送信息(output-write)
- out.wirte("TODO");
-
-
-
-
- String response="",lineStr = in.readLine();
- while(lineStr!=null){
- response += lineStr;
- lineStr = in.readLine();
- }
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
- finally{
- if(serverSocket!=null)
- serverSocket.close();
- }
- }
2.1 UDP的JAVA代码大致如下
服务端代码
- <span style="font-size:14px;">public class ServerDatagramSocket
- {
-
- public static void main(String[] args)
- {
- try
- {
-
- DatagramSocket ds = new DatagramSocket(10010);
-
-
-
- byte[] data=new byte[1024];
-
- DatagramPacket receiveDp=new DatagramPacket(data, data.length);
-
- ds.receive(receiveDp);
-
- byte[] receiveByte=receiveDp.getData();
- String receiveContent=new String(receiveByte,0,receiveByte.length);
-
-
-
-
- InetAddress clientIp=receiveDp.getAddress();
-
- int port=receiveDp.getPort();
- String sendContent="hello back";
- byte[] sendByte=sendContent.getBytes();
-
- DatagramPacket sendDp=new DatagramPacket(sendByte, sendByte.length, clientIp, port);
-
- ds.send(sendDp);
- }
- catch (Exception e) {
-
- }
- finally{
-
- ds.close();
- }
- }
- }</span>
客户端代码
- <span style="font-size:14px;">public static void main(String[] args) {
-
- try
- {
-
- DatagramSocket ds=new DatagramSocket();
-
-
-
- String sendContent="hello";
- String host="127.0.0.1";
- int port=10001;
-
- byte[] sendByte=sendContent.getBytes();
-
- InetAddress server=InetAddress.getByName(host);
-
- DatagramPacket sendDp=new DatagramPacket(sendByte, sendByte.length, server, port);
-
-
- ds.send(sendDp);
-
-
-
- byte[] data=new byte[1024];
-
- DatagramPacket receiveDp=new DatagramPacket(data, data.length);
-
- ds.receive(receiveDp);
-
- byte[] receiveByte=receiveDp.getData();
- int len=receiveDp.getLength();
- String receiveContent=new String(receiveByte, 0, len);
- System.out.println(receiveContent);
- }
- catch (Exception e)
- {
-
- }
- finally{
-
- ds.close();
- }
- }
- }</span>
3 应用(TCP和多线程的应用)
在工作中遇到如下问题:一个算法执行程序可以部署到多台机器上,一台机器上可以部署多个算法执行程序,即算法程序和机器是多对多的关系。现在要求用户只需要输入提供算法的名称和相关算法参数(如数据路径),然后返回数据处理结果。
解决方案:
服务端为多台部署算法程序的机器。客户端响应用户算法的请求,并从服务端多台机器中选择最优机器执行用户的算法处理。由于一台服务端机器可能会同时处理多个用户算法请求,而每个算法处理数据的过程(数据下载,数据处理,处理结果上传)是个比较长的时间,所以服务端程序采用多线程并行执行多个算法的请求。这个用一个共享FTP来在服务端和客户端共享处理的数据和上传处理后的数据。服务端和客户端通过TCP协议保证可靠的、面向连接的通信服务。整个系统架构如下图
- public class ClientSocketApplication {
-
- public static void main(String[] args)
- {
-
- String response=sendMsg("10.3.11.33",9090);
- if(response==null)
- System.out.println("Socket服务器连接失败:请检查安装的Socket服务器是否正常工作!");
-
- processData("send algorithem name and its parameters");
- }
-
-
-
- public static String sendMsg(String sendContent, String serverMachineIp, int port) throws Exception{
-
- String response=null;
-
-
- Socket clientSocket = new Socket(String serverMachineIp, int port);
- int timeout=1000;
- clientSocket.connect(sa, timeout);
-
- OutputStream outStream = clientSocket.getOutputStream();
- BufferedWriter out = new BufferedWriter(new OutputStreamWriter(outStream));
-
- InputStream inStream = clientSocket.getInputStream();
- BufferedReader in = new BufferedReader(new InputStreamReader(inStream));
-
- try{
-
- out.wirte(sendContent);
-
-
- String lineStr = in.readLine();
- while(lineStr!=null){
- response += lineStr;
- lineStr = in.readLine();
- }
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
- finally{
-
- out.close();
- in.close();
-
- s.close();
- }
-
-
- return response;
- }
-
-
-
-
- public static void processData(String algName, Map<String, String> reqValues) throws ManagerException
- {
-
- CMachine optCMachine=getOptCMachine(algName);
- String sendRequest=createReqStr(algName, reqValues);
-
-
- try {
- String response = sendMsg(reqStr, optCMachine.getIp(),optCMachine.getPort());
- if ( !response.eques("processing") || !response.eques("successfull")) {
- throw new ManagerException("向服务器发送计算请求失败: " + response);
- }
-
-
- String monitDir = FileTool.getNodeManagerShareDir() + "/" + jobID + "/" + algName + "/output";
- File logFile = new File(monitDir + "/log.xml");
- for (;;) {
- if (logFile.exists()) {
- logger.info("Log文件已经上传,算法处理完成; 开始打包文件");
- ZipTool.zipFiles(monitDir);
- break;
- } else {
- Thread.sleep(30000);
- logger.info("请求正在处理中...: " + algName);
- }
- }
- } catch (Exception e) {
- throw new ManagerException("算法服务器处理请求时出错,请与节点管理员联系查看原因");
- }
- }
- }
网络Socket编程及实例
标签:步骤 适合 因此 管理 host ntc network close address
原文地址:https://www.cnblogs.com/klb561/p/9011615.html