热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

8.9.网络编程_Socket远程调用机制

1.网络编程1.1.网络编程概述:通过通信线路(有线或无线)可以把不同地理位置且相互独立的计算机连同其外部设备连接起来,组成计算机网络。在操作系统、网络管理软件及网络通信协议的管理

1.网络编程

1.1.网络编程概述:

  通过通信线路(有线或无线)可以把不同地理位置且相互独立的计算机连同其外部设备连接起来,组成计算机网络。在操作系统、网络管理软件及网络

通信协议的管理和协调下,可以实现计算机之间的资源共享和信息的传递

  网络编程是指用来实现网络互联的不同计算机上运行的程序间可以进行数据交换。对我们来说即如何用编程语言 java 实现计算机网络中不同计算机之间

的通信

1.2.网络通信三要素

  1.2.1:IP 地址: 网络中计算机的唯一标识;32bit(4 字节),一般用“点分十进制”表示,如 192.168.1.158;

    IP 地址=网络地址+主机地址 可分类:

    8.9.网络编程_Socket 远程调用机制

  Java 编程中可使用 InetAddress 类来操纵 IP 地址

public static void main(String[] args) throws UnknownHostException {
   InetAddress localHost = InetAddress.getLocalHost();
   System.out.println(localHost.getHostAddress());
   System.out.println(localHost.getHostName());
}

  1.2.2:端口号:用于标识进程的逻辑地址,不同进程的标识;有效端口:0-65535,其中 0-1024 系统使用或保留端口

  1.2.3:传输协议 :通讯的规则常见协议: UDP(用户数据报协议)、TCP(传输控制协议)

    8.9.网络编程_Socket 远程调用机制

1.3. 网络模型

  计算机网络之间以何种规则进行通信,就是网络模型所研究的问题

  网络模型一般是指 OSI 七层参考模型和 TCP/IP 五层参考模型

  8.9.网络编程_Socket 远程调用机制

  每一层实现各自的功能和协议,并且都为上一层提供业务功能。为了提供这种业务功能,下一层将上一层中的数据并入到本层的数据域中,

然后通过加入报头或报尾来实现该层业务功能,该过程叫做数据封装。用户的数据要经过一次次包装,最后转化成可以在网络上传输的信号,

发送到网络上。当到达目标计算机后,再执行相反的数据拆包过程

  8.9.网络编程_Socket 远程调用机制

  1.物理层:主要定义物理设备标准,如网线的接口类型、光纤的接口类型、各种传输介质的传输速率等。主要作用是将数据最终编码为用 0、1

标识的比特流,通过物理介质传输。这一层的数据叫做比特

  2.数据链路层:主要将接收到的数据进行 MAC 地址(网卡地址)的封装与解封装。常把这一层的数据叫做帧。这一层常工作的设备是交换机

  3.网络层:主要将接收到的数据进行 IP 地址的封装与解封装。常把这一层的数据叫做数据包。这一层设备是路由器

  4.传输层:定义了一些数据传输的协议和端口号。主要将接收的数据进行分段和传输,到达目的地址后在进行重组。常把这一层的数据叫做段

  5.会话层:通过传输层建立数据传输的通路。主要在系统之间发起会话或者接收会话请求

  6.表示层:主要进行对接收数据的解释、加密与解密、压缩与解压缩。确保一个系统的应用层发送的数据能被另一个系统的应用层识别

  7.应用层:主要是为一些终端应用程序提供服务。直接面对着用户的

1.4.Socket 远程调用机制

4.1.Socket 概述

  Socket,又称为套接字,用于描述 IP 地址和端口。应用程序通常通过 socket向网络发出请求或者应答网络请求。

  Socket 就是为网络编程提供的一种机制:通信两端都有 socket;网络通信其实就是 socket 之间的通信;数据在两个 socket 之间通过 IO 传输。

  网络编程也称作为 Socket 编程,套接字编程。Socket通信是 Client/Server 模型

4.2.基于 UDP 协议的 Socket 通信:核心类:DatagramSocket

  客户端:

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
/**
 * Created by Administrator on 2018/6/7.
 */
public class SocketUDP {
    public static void main(String[] args) throws Exception {
        // 创建发送端 Socket 服务对象
        DatagramSocket dSocket = null;
        try {
            dSocket = new DatagramSocket();
            // 创建数据,打包数据
            String message = "hello ,are u UDP ?";
            byte[] bys = message.getBytes();
            int length = bys.length;
            InetAddress address = InetAddress.getByName("localhost");
            int port = 12621;
            DatagramPacket dPacket = new DatagramPacket(bys, length, address, port);
            // 发送数据
            dSocket.send(dPacket);
            // 资源释放
            dSocket.close();
        } catch (SocketException e) {
            e.printStackTrace();
        }
    }
}

  接收端:

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

/**
 * Created by Administrator on 2018/6/7.
 */
public class SocketUDPServer {
    public static void main(String[] args) throws Exception {
        //创建接收端 Socket 服务对象
        DatagramSocket dSocket = new DatagramSocket(12621);
        //创建数据包(接收容器)
        byte[] bys = new byte[1024];
        DatagramPacket dPacket = new DatagramPacket(bys, bys.length);
        //调用接收方法
        dSocket.receive(dPacket);
        //数据包解析
        InetAddress address = dPacket.getAddress();
        String hostAddress = address.getHostAddress();
        byte[] data = dPacket.getData();
        String message = new String(data);
        System.out.println(hostAddress+"*********:"+message);
        //资源释放
        dSocket.close();
    }
}

4.3. 基于 TCP 协议的 Socket 通信

  客户端 :核心 API:Socket 

import java.io.OutputStream;
import java.net.Socket;

/**
 * Created by Administrator on 2018/6/7.
 */
public class SocketTCPClient {
    public static void main(String[] args) throws  Exception{
        //创建客户端的 socket 服务,指定目的主机和端口
        Socket s = new Socket("127.0.0.1", 13131);
        //通过 socket 获取输出流,写数据
        OutputStream outputStream = s.getOutputStream();
        outputStream.write("hello ,this is tcp?".getBytes());
        //释放资源
        s.close();
    }
}

  服务端 :核心 API:ServerSocket

import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * Created by Administrator on 2018/6/7.
 */
public class SocketTCPServer {
    public static void main(String[] args) throws Exception {
        //建立服务端 socket 服务,并且监听一个端口
        ServerSocket ss = new ServerSocket(13131);
        //监听连接
        Socket s = ss.accept();
        //获取输入流,读取数据
        InputStream inputStream = s.getInputStream();
        byte[] bys = new byte[1024];
        int len = inputStream.read(bys);
        System.out.println(new String(bys, 0, len));
        //关闭客户端
        s.close();
        //关闭服务端,一般服务端不关闭
        ss.close();
    }
}

 

 服务端代码2:

import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;

public class ServiceServer {

    public static void main(String[] args) throws Exception {

        // 创建一个serversocket,绑定到本机的8899端口上
        ServerSocket server = new ServerSocket();
        server.bind(new InetSocketAddress("localhost", 8899));

        // 接受客户端的连接请求;accept是一个阻塞方法,会一直等待,直到有客户端请求连接才返回
        while (true) {
            Socket socket = server.accept();
       //业务实现
new Thread(new ServiceServerTask(socket)).start(); } } }

业务类:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;

public class ServiceServerTask implements Runnable{
    Socket socket ;
    InputStream in=null;
    OutputStream out = null;
    
    public ServiceServerTask(Socket socket) {
        this.socket = socket;
    }

    //业务逻辑:跟客户端进行数据交互
    @Override
    public void run() {
         try {
            //从socket连接中获取到与client之间的网络通信输入输出流 
            in = socket.getInputStream();
            out = socket.getOutputStream();            
            
            BufferedReader br = new BufferedReader(new InputStreamReader(in));
            //从网络通信输入流中读取客户端发送过来的数据
            //注意:socketinputstream的读数据的方法都是阻塞的 
            String param = br.readLine();
            
            /**
             * 可以根据客户端发过来的调用类名、调用方法名、调用该参数来灵活调用
             * 《反射》
             */
            
            GetDataServiceImpl getDataServiceImpl = new GetDataServiceImpl();
            String result = getDataServiceImpl.getData(param);
            
            
            //将调用结果写到sokect的输出流中,以发送给客户端
            PrintWriter pw = new PrintWriter(out);
            pw.println(result);
            pw.flush();
            
        } catch (IOException e) {
             
            e.printStackTrace();
        }finally{
            try {
                in.close();
                out.close();
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }    
        }        
    }
}

接口类:

public class GetDataServiceImpl {
    
    public String getData(String param){    
        return "ok-"+param;
    }
}

客户端:

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;

public class ServiceClient {

    public static void main(String[] args) throws Exception {
        
        /*ServiceIterface service = ProxyUtils.getProxy(ServiceIterface.class,"methodA",hostname,port);
        Result = service.methodA(parameters);*/
        
        // 向服务器发出请求建立连接
        Socket socket = new Socket("localhost", 8899);
        // 从socket中获取输入输出流
        InputStream inputStream = socket.getInputStream();
        OutputStream outputStream = socket.getOutputStream();

        PrintWriter pw = new PrintWriter(outputStream);
        pw.println("hello");
        pw.flush();

        BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
        String result = br.readLine();
        System.out.println(result);
        
        inputStream.close();
        outputStream.close();
        socket.close();    
    }
}

 

 

 

  

  


  

  

  


  

 

 

  

   

  


推荐阅读
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • 本文介绍了Python高级网络编程及TCP/IP协议簇的OSI七层模型。首先简单介绍了七层模型的各层及其封装解封装过程。然后讨论了程序开发中涉及到的网络通信内容,主要包括TCP协议、UDP协议和IPV4协议。最后还介绍了socket编程、聊天socket实现、远程执行命令、上传文件、socketserver及其源码分析等相关内容。 ... [详细]
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • 阿,里,云,物,联网,net,core,客户端,czgl,aliiotclient, ... [详细]
  • 本文介绍了Windows操作系统的版本及其特点,包括Windows 7系统的6个版本:Starter、Home Basic、Home Premium、Professional、Enterprise、Ultimate。Windows操作系统是微软公司研发的一套操作系统,具有人机操作性优异、支持的应用软件较多、对硬件支持良好等优点。Windows 7 Starter是功能最少的版本,缺乏Aero特效功能,没有64位支持,最初设计不能同时运行三个以上应用程序。 ... [详细]
  • 本文讨论了在手机移动端如何使用HTML5和JavaScript实现视频上传并压缩视频质量,或者降低手机摄像头拍摄质量的问题。作者指出HTML5和JavaScript无法直接压缩视频,只能通过将视频传送到服务器端由后端进行压缩。对于控制相机拍摄质量,只有使用JAVA编写Android客户端才能实现压缩。此外,作者还解释了在交作业时使用zip格式压缩包导致CSS文件和图片音乐丢失的原因,并提供了解决方法。最后,作者还介绍了一个用于处理图片的类,可以实现图片剪裁处理和生成缩略图的功能。 ... [详细]
  • 代理模式的详细介绍及应用场景
    代理模式是一种在软件开发中常用的设计模式,通过在客户端和目标对象之间增加一层中间层,让代理对象代替目标对象进行访问,从而简化系统的复杂性。代理模式可以根据不同的使用目的分为远程代理、虚拟代理、Copy-on-Write代理、保护代理、防火墙代理、智能引用代理和Cache代理等几种。本文将详细介绍代理模式的原理和应用场景。 ... [详细]
  • C# 7.0 新特性:基于Tuple的“多”返回值方法
    本文介绍了C# 7.0中基于Tuple的“多”返回值方法的使用。通过对C# 6.0及更早版本的做法进行回顾,提出了问题:如何使一个方法可返回多个返回值。然后详细介绍了C# 7.0中使用Tuple的写法,并给出了示例代码。最后,总结了该新特性的优点。 ... [详细]
  • PHP中的单例模式与静态变量的区别及使用方法
    本文介绍了PHP中的单例模式与静态变量的区别及使用方法。在PHP中,静态变量的存活周期仅仅是每次PHP的会话周期,与Java、C++不同。静态变量在PHP中的作用域仅限于当前文件内,在函数或类中可以传递变量。本文还通过示例代码解释了静态变量在函数和类中的使用方法,并说明了静态变量的生命周期与结构体的生命周期相关联。同时,本文还介绍了静态变量在类中的使用方法,并通过示例代码展示了如何在类中使用静态变量。 ... [详细]
  • 后台获取视图对应的字符串
    1.帮助类后台获取视图对应的字符串publicclassViewHelper{将View输出为字符串(注:不会执行对应的ac ... [详细]
  • 个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ... [详细]
  • 猜字母游戏
    猜字母游戏猜字母游戏——设计数据结构猜字母游戏——设计程序结构猜字母游戏——实现字母生成方法猜字母游戏——实现字母检测方法猜字母游戏——实现主方法1猜字母游戏——设计数据结构1.1 ... [详细]
  • 本文总结了在开发中使用gulp时的一些技巧,包括如何使用gulp.dest自动创建目录、如何使用gulp.src复制具名路径的文件以及保留文件夹路径的方法等。同时介绍了使用base选项和通配符来保留文件夹路径的技巧,并提到了解决带文件夹的复制问题的方法,即使用gulp-flatten插件。 ... [详细]
  • 恶意软件分析的最佳编程语言及其应用
    本文介绍了学习恶意软件分析和逆向工程领域时最适合的编程语言,并重点讨论了Python的优点。Python是一种解释型、多用途的语言,具有可读性高、可快速开发、易于学习的特点。作者分享了在本地恶意软件分析中使用Python的经验,包括快速复制恶意软件组件以更好地理解其工作。此外,作者还提到了Python的跨平台优势,使得在不同操作系统上运行代码变得更加方便。 ... [详细]
  • 2021最新总结网易/腾讯/CVTE/字节面经分享(附答案解析)
    本文分享作者在2021年面试网易、腾讯、CVTE和字节等大型互联网企业的经历和问题,包括稳定性设计、数据库优化、分布式锁的设计等内容。同时提供了大厂最新面试真题笔记,并附带答案解析。 ... [详细]
author-avatar
灰包蛋啦_199
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有