基本原理 要實現(xiàn)網(wǎng)絡機器間的通訊,首先得來看看計算機系統(tǒng)網(wǎng)絡通信的基本原理,在底層層面去看,網(wǎng)絡通信需要做的就是將流從一臺計算機傳輸?shù)搅硗庖慌_計算機,基于傳輸協(xié)議和網(wǎng)絡 IO 來實現(xiàn),其中傳輸協(xié)議比較出名的有 http、tcp、 udp 等等,http、tcp、udp 都是在基于Socket 概念上為某類應用場景而擴展出的傳輸協(xié)議,網(wǎng)絡IO,主要有bio、nio、aio 三種方式,所有的分布式應用通訊都基于這個原理而實現(xiàn),只是為了應用的易用,各種語言通常都會提供一些更為貼近應用易用的應用層協(xié)議。 應用級協(xié)議 遠程服務通訊,需要達到的目標是在一臺計算機發(fā)起請求,另外一臺機器在接收到請求后進行相應的處理并將結果返回給請求端,這其中又會有諸如 onewayrequest、同步請求、異步請求等等請求方式,按照網(wǎng)絡通信原理,需要實現(xiàn)這個需要做的就是將請求轉換成流,通過傳輸協(xié)議傳輸至遠端,遠端計算機在接收到請求的流后進行處理,處理完畢后將結果轉化為流,并通過傳輸協(xié)議返回給調用端。原理是這樣的,但為了應用的方便,業(yè)界推出了很多基于此原理之上的應用級的協(xié)議,使得大家可以不用去直接操作這么底層的東西,通常應用級的遠程通信協(xié)議會提供: 1.為了避免直接做流操作這么麻煩,提供一種更加易用或貼合語言的標準傳輸格式;2.網(wǎng)絡通信機制的實現(xiàn),就是替你完成了將傳輸格式轉化為流,通過某種傳輸協(xié)議傳輸至遠端計算機,遠端計算機在接收到流后轉化為傳輸格式,并進行存儲或以某種方式通知遠端計算機。 所以在學習應用級的遠程通信協(xié)議時,我們可以帶著這幾個問題進行學習: 1.傳輸?shù)臉藴矢袷绞鞘裁?2.怎么樣將請求轉化為傳輸?shù)牧?3.怎么接收和處理流?4.傳輸協(xié)議是? 不過應用級的遠程通信協(xié)議并不會在傳輸協(xié)議上做什么多大的改進,主要是在流操作方面,讓應用層生成流和處理流的這個過程更加的貼合所使用的語言或標準,至于傳輸協(xié)議則通常都是可選的,在java 領域中知名的有:RMI、 XML-RPC、Binary-RPC、SOAP、CORBA、JMS,來具體的看看這些遠程通信的應用級協(xié)議: RMIRMI 是個典型的為java 定制的遠程通信協(xié)議,我們都知道,在 singlevm 中,我們可以通過直接調用javaobjectinstance 來實現(xiàn)通信,那么在遠程通信時,如果也能按照這種方式當然是最好了,這種遠程通信的機制成為RPC(RemoteProcedureCall),RMI 正是朝著這個目標而誕生的。 來看下基于RMI 的一次完整的遠程通信過程的原理: 1.客戶端發(fā)起請求,請求轉交至RMI 客戶端的stub 類;2.stub 類將請求的接口、方法、參數(shù)等信息進行序列化;3.基于socket 將序列化后的流傳輸至服務器端;4.服務器端接收到流后轉發(fā)至相應的skelton 類;5.skelton 類將請求的信息反序列化后調用實際的處理類;6.處理類處理完畢后將結果返回給 skelton 類;7.Skelton 類將結果序列化,通過socket 將流傳送給客戶端的 stub;8.stub 在接收到流后反序列化,將反序列化后的JavaObject 返回給調用者。 根據(jù)原理來回答下之前學習應用級協(xié)議帶著的幾個問題: 1.傳輸?shù)臉藴矢袷绞鞘裁?是JavaObjectStream。2.怎么樣將請求轉化為傳輸?shù)牧?基于Java 串行化機制將請求的javaobject 信息轉化為流。3.怎么接收和處理流?根據(jù)采用的協(xié)議啟動相應的監(jiān)聽端口,當有流進入后基于Java 串行化機制將流進行反序列化,并根據(jù)RMI 協(xié)議獲取到相應的處理對象信息,進行調用并處理,處理完畢后的結果同樣基于java 串行化機制進行返回。4.傳輸協(xié)議是?Socket。 XML-RPCXML-RPC 也是一種和RMI 類似的遠程調用的協(xié)議,它和RMI 的不同之處在于它以標準的 xml 格式來定義請求的信息(請求的對象、方法、參數(shù)等),這樣的好處是什么呢,就是在跨語言通訊的時候也可以使用。 來看下XML-RPC 協(xié)議的一次遠程通信過程: 1.客戶端發(fā)起請求,按照XML-RPC 協(xié)議將請求信息進行填充;2.填充完畢后將xml 轉化為流,通過傳輸協(xié)議進行傳輸;3.接收到在接收到流后轉換為xml,按照XML-RPC 協(xié)議獲取請求的信息并進行處理;4.處理完畢后將結果按照XML- RPC 協(xié)議寫入xml 中并返回。 同樣來回答問題: 1.傳輸?shù)臉藴矢袷绞?標準格式的XML。2.怎么樣將請求轉化為傳輸?shù)牧? 將XML 轉化為流。3.怎么接收和處理流?通過監(jiān)聽的端口獲取到請求的流,轉化為XML,并根據(jù)協(xié)議獲取請求的信息,進行處理并將結果寫入XML 中返回。4. 傳輸協(xié)議是?Http。 Binary-RPCBinary-RPC 看名字就知道和XML-RPC 是差不多的了,不同之處僅在于傳輸?shù)臉藴矢袷接蒟ML 轉為了二進制的格式。 同樣來回答問題: 1.傳輸?shù)臉藴矢袷绞?標準格式的二進制文件。2.怎么樣將請求轉化為傳輸?shù)牧?將二進制格式文件轉化為流。3.怎么接收和處理流?通過監(jiān)聽的端口獲取到請求的流,轉化為二進制文件,根據(jù)協(xié)議獲取請求的信息,進行處理并將結果寫入XML 中返回。4.傳輸協(xié)議是?Http。 SOAPSOAP 原意為SimpleObjectAccessProtocol,是一個用于分布式環(huán)境的、輕量級的、基于XML 進行信息交換的通信協(xié)議,可以認為SOAP 是XMLRPC 的高級版,兩者的原理完全相同,都是http+XML,不同的僅在于兩者定義的XML 規(guī)范不同,SOAP 也是Webservice 采用的服務調用協(xié)議標準,因此在此就不多加闡述了。 CORBACommonObjectRequestBrokerArchitecture(公用對象請求代理[調度]程序體系結構),是一組用來定義"分布式對象系統(tǒng)"的標準,由 OMG(ObjectMenagementGroup)作為發(fā)起和標準制定單位。CORBA 的目的是定義一套協(xié)議,符合這個協(xié)議的對象可以互相交互,不論它們是用什么樣的語言寫的,不論它們運行于什么樣的機器和操作系統(tǒng)。CORBA 在我看來是個類似于SOA 的體系架構,涵蓋可選的遠程通信協(xié)議,但其本身不能列入通信協(xié)議這里來講,而且CORBA 基本淘汰,再加上對CORBA 也不怎么懂,在此就不進行闡述了。 JMSJMS 呢,是實現(xiàn)java 領域遠程通信的一種手段和方法,基于JMS 實現(xiàn)遠程通信時和RPC 是不同的,雖然可以做到RPC 的效果,但因為不是從協(xié)議級別定義的,因此我們不認為JMS 是個RPC 協(xié)議,但它確實是個遠程通信協(xié)議,在其他的語言體系中也存在著類似JMS 的東西,可以統(tǒng)一的將這類機制稱為消息機制,而消息機制呢,通常是高并發(fā)、分布式領域推薦的一種通信機制,這里的主要一個問題是容錯(詳細見ErLang 論文)。 來看JMS 中的一次遠程通信的過程: 1.客戶端將請求轉化為符合JMS 規(guī)定的Message;2.通過JMSAPI 將Message 放入JMSQueue 或Topic 中;3.如為JMSQueue,則發(fā)送中相應的目標Queue 中,如為Topic,則發(fā)送給訂閱了此Topic 的JMSQueue。4.處理端則通過輪訓 JMSQueue,來獲取消息,接收到消息后根據(jù)JMS 協(xié)議來解析Message 并處理。 回答問題: 1.傳輸?shù)臉藴矢袷绞?JMS 規(guī)定的Message。2.怎么樣將請求轉化為傳輸?shù)牧?將參數(shù)信息放入Message 中即可。3.怎么接收和處理流?輪訓JMSQueue 來接收Message,接收到后進行處理,處理完畢后仍然是以Message 的方式放入 Queue 中發(fā)送或Multicast。4.傳輸協(xié)議是?不限。 基于JMS 也是常用的實現(xiàn)遠程異步調用的方法之一。
創(chuàng)新互聯(lián)是一家專注于網(wǎng)站建設、成都網(wǎng)站設計與策劃設計,懷來網(wǎng)站建設哪家好?創(chuàng)新互聯(lián)做網(wǎng)站,專注于網(wǎng)站建設10年,網(wǎng)設計領域的專業(yè)建站公司;建站業(yè)務涵蓋:懷來等地區(qū)。懷來做網(wǎng)站價格咨詢:18980820575
Java 遠程處理
Java遠程方法調用(RMI)提供了Java程序語言的遠程通訊功能,這種特性使客戶機上運行的程序可以調用遠程服務器上的對象,使Java編程人員能夠在網(wǎng)絡環(huán)境中分布操作。
創(chuàng)建一個簡單的Java分布式遠程方法調用程序可以按以下幾個步驟操作,
一、定義遠程接口:
在 Java 中,遠程對象是實現(xiàn)遠程接口的類的實例, 遠程接口聲明每個要遠程調用的方法。在需要創(chuàng)建一個遠程對象的時候,我們通過傳遞一個接口來隱藏基層的實施細節(jié),客戶通過接口句柄發(fā)送消息即可。
遠程接口具有如下特點:
1) 遠程接口必須為public屬性。如果不這樣,除非客戶端與遠程接口在同一個包內,否則 當試圖裝入實現(xiàn)該遠程接口的遠程對象時,調用會得到錯誤結果。
2) 遠程接口必須擴展接口java.rmi.Remote。
3) 除與應用程序本身特定的例外之外,遠程接口中的每個方法都必須在自己的throws從句中 聲明java.rmi.RemoteException。(或 RemoteException 的父類)。
4) 作為參數(shù)或返回值傳遞的一個遠程對象(不管是直接,還是本地對象中嵌入)必須聲明為遠 程接口,而不應聲明為實施類。
下面是遠程接口的定義
[java] view plaincopy
package test;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.math.BigInteger;
public interface Fib extends Remote {
public int getFib(int n) throws RemoteException;
// public BigInteger getFib(BigInteger n) throws RemoteException;
}
二、實現(xiàn)遠程接口:
遠程對象實現(xiàn)類必須擴展遠程對象java.rmi.UnicastRemoteObject類,并實現(xiàn)所定義的遠程接口。遠程對象的實現(xiàn)類中包含實現(xiàn)每個遠程接口所指定的遠程方法的代碼。這個類也可以含有附加的方法,但客戶只能使用遠程接口中的方法。因為客戶是指向接口的一個句柄,而不是它的哪個類。必須為遠程對象定義構造函數(shù),即使只準備定義一個默認構造函數(shù),用它調用基礎類構造函數(shù)。因為基礎類構造函數(shù)可能會拋出 java.rmi.RemoteException,所以即使別無它用必須拋出java.rmi.RemoteException例外。
以下是遠程對象實現(xiàn)類的聲明:
[java] view plaincopy
package test;
import java.math.BigInteger;
import java.rmi.*;
import java.rmi.server.UnicastRemoteObject;
public class FibImp extends UnicastRemoteObject implements Fib {
public FibImp() throws RemoteException {
super();
}
public int getFib(int n) throws RemoteException {
return n+2;
}
}
三、編寫服務器類:
包含 main 方法的類可以是實現(xiàn)類自身,也可以完全是另一個類。下面通過RmiSampleServer 來創(chuàng)建一個遠程對象的實例,并通過java.rmi.registry.LocateRegistry類的createRegistry 方法從指定端口號啟動注冊服務程序,也可以通過執(zhí)行 rmiregistry 命令啟動注冊服務程序,注冊服務程序的缺省運行端口為 1099。必須將遠程對象名字綁定到對遠程對象的引用上: Naming.rebind("http://localhost:8808/SAMPLE-SERVER" , Server);
以下是服務器類的聲明:
[java] view plaincopy
package test;
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
public class FibonacciServer {
/**
* @param args
*/
public static void main(String[] args) {
try {
LocateRegistry.createRegistry(8804);
FibImp f = new FibImp();
// 注冊到 registry 中
Naming.rebind("http://localhost:8804/SAMPLE-SERVER", f);
System.out.println("fib server ready");
} catch (RemoteException re) {
System.out.println("Exception in FibonacciImpl.main: " + re);
} catch (MalformedURLException e) {
System.out.println("MalformedURLException " + e);
}
}
}
四、編寫使用遠程服務的客戶機類:
客戶機類的主要功能有兩個,一是通過Naming.lookup方法來構造注冊服務程序 stub 程序實例,二是調用服務器遠程對象上的遠程方法。
以下是客戶端類的聲明:
[java] view plaincopy
package testClient;
import test.Fib;
import java.math.BigInteger;
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
public class FibClient {
/**
* @param args
*/
public static void main(String[] args) {
String url = "http://localhost:8804/SAMPLE-SERVER";
try {
Fib calc = (Fib) Naming.lookup(url);
for (int i = 0; i 10; ++i) {
int f = calc.getFib(i);
System.out.println(f);
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (RemoteException e) {
e.printStackTrace();
} catch (NotBoundException e) {
e.printStackTrace();
}
}
}
JNI是JavaNativeInterface的縮寫,中文為JAVA本地調用。從Java1.1開始,JavaNativeInterface(JNI)標準成為java平臺的一部分,它允許Java代碼和其他語言寫的代碼進行交互。JNI一開始是為了本地已編譯語言,尤其是C和C++而設計的,但是它并不妨礙你使用其他語言,只要調用約定受支持就可以了。
使用java與本地已編譯的代碼交互,通常會喪失平臺可移植性。但是,有些情況下這樣做是可以接受的,甚至是必須的,比如,使用一些舊的庫,與硬件、操作系統(tǒng)進行交互,或者為了提高程序的性能。JNI標準至少保證本地代碼能工作在任何Java虛擬機實現(xiàn)下。
------------------------------------------------------------------
編寫帶有native聲明的方法的java類
·使用javac命令編譯所編寫的java類
·使用javah?jnijava類名生成擴展名為h的頭文件
·使用C/C++實現(xiàn)本地方法
·將C/C++編寫的文件生成動態(tài)連接庫
·ok
1)編寫java程序:這里以HelloWorld為例。
代碼1:
classHelloWorld{
publicnativevoiddisplayHelloWorld();
static{
System.loadLibrary("hello");
}
publicstaticvoidmain(String[]args){
newHelloWorld().displayHelloWorld();
}
}
聲明native方法:如果你想將一個方法做為一個本地方法的話,那么你就必須聲明改方法為native的,并且不能實現(xiàn)。其中方法的參數(shù)和返回值在后面講述。Load動態(tài)庫:System.loadLibrary("hello");加載動態(tài)庫(我們可以這樣理解:我們的方法displayHelloWorld()沒有實現(xiàn),但是我們在下面就直接使用了,所以必須在使用之前對它進行初始化)這里一般是以static塊進行加載的。同時需要注意的是System.loadLibrary();的參數(shù)“hello”是動態(tài)庫的名字。
2)編譯
沒有什么好說的了javacHelloWorld.java
3)生成擴展名為h的頭文件javah?
jniHelloWorld頭文件的內容:/*DONOTEDITTHISFILE-itismachinegenerated*/
1.include
/*HeaderforclassHelloWorld*/
1.ifndef_Included_HelloWorld
2.define_Included_HelloWorld
3.ifdef__cplusplus
extern"C"{
1.endif
/*
*Class:HelloWorld
*Method:displayHelloWorld
*Signature:()V
*/
JNIEXPORTvoidJNICALLJava_HelloWorld_displayHelloWorld(JNIEnv*,jobject);
1.ifdef__cplusplus
}
1.endif
2.endif
(這里我們可以這樣理解:這個h文件相當于我們在java里面的接口,這里聲明了一個Java_HelloWorld_displayHelloWorld(JNIEnv*,jobject);方法,然后在我們的本地方法里面實現(xiàn)這個方法,也就是說我們在編寫C/C++程序的時候所使用的方法名必須和這里的一致)。
4)編寫本地方法實現(xiàn)和由javah命令生成的頭文件里面聲明的方法名相同的方法。
代碼2:
1#include"jni.h"
2#include"HelloWorld.h"
3//#includeotherheaders
4JNIEXPORTvoidJNICALLJava_HelloWorld_displayHelloWorld(JNIEnv*env,jobjectobj)
{
printf("Helloworld!\n");
return;
}
注意代碼2中的第1行,需要將jni.h(該文件可以在%JAVA_HOME%/include文件夾下面找到)文件引入,因為在程序中的JNIEnv、jobject等類型都是在該頭文件中定義的;另外在第2行需要將HelloWorld.h頭文件引入(我是這么理解的:相當于我們在編寫java程序的時候,實現(xiàn)一個接口的話需要聲明才可以,這里就是將HelloWorld.h頭文件里面聲明的方法加以實現(xiàn)。當然不一定是這樣)。然后保存為HelloWorldImpl.c就ok了。
5)生成動態(tài)庫
這里以在Windows中為例,需要生成dll文件。在保存HelloWorldImpl.c文件夾下面,使用VC的編譯器cl成。cl-I%java_home%\include-I%java_home%\include\win32-LDHelloWorldImp.c-Fehello.dll注意:生成的dll文件名在選項-Fe后面配置,這里是hello,因為在HelloWorld.java文件中我們loadLibary的時候使用的名字是hello。當然這里修改之后那里也需要修改。另外需要將-I%java_home%\include-I%java_home%\include\win32參數(shù)加上,因為在第四步里面編寫本地方法的時候引入了jni.h文件。
6)運行程序javaHelloWorld就ok.
---------------------------------------------------------------
下面是一個簡單的例子實現(xiàn)打印一句話的功能,但是用的c的printf最終實現(xiàn)。一般提供給java的jni接口包括一個so文件(封裝了c函數(shù)的實現(xiàn))和一個java文件(需要調用path的類)。
1.JNI的目的是使java方法中能夠調用c實現(xiàn)的一些函數(shù),比如以下的java類,就需要調用一個本地函數(shù)testjni(一般聲明為privatenative類型),首先需要創(chuàng)建文件weiqiong.java,內容如下:
classweiqiong{static{System.loadLibrary("testjni");//載入靜態(tài)庫,test函數(shù)在其中實現(xiàn)}privatenativevoidtestjni();//聲明本地調用publicvoidtest(){testjni();}publicstaticvoidmain(Stringargs[]){weiqionghaha=newweiqiong();haha.test();}}
2.然后執(zhí)行javacweiqiong.java,如果沒有報錯,會生成一個weiqiong.class。
3.然后設置classpath為你當前的工作目錄,如直接輸入命令行:setclasspath=weiqiong.class所在的完整目錄(如c:\test)再執(zhí)行javahweiqiong,會生成一個文件weiqiong.h文件,其中有一個函數(shù)的聲明如下:
JNIEXPORTvoidJNICALLJava_weiqiong_testjni(JNIEnv*,jobject);
4.創(chuàng)建文件testjni.c將上面那個函數(shù)實現(xiàn),內容如下:
1.include
2.include
JNIEXPORTvoidJNICALLJava_weiqiong_testjni(JNIEnv*env,jobjectobj){printf("haha---------gointoc!!!\n");}
5.為了生成.so文件,創(chuàng)建makefile文件如下:
libtestjni.so:testjni.omakefilegcc-Wall-rdynamic-shared-olibtestjni.sotestjni.otestjni.o:testjni.cweiqiong.hgcc-Wall-ctestjni.c-I./-I/usr/java/j2sdk1.4.0/include-I/usr/java/j2sdk1.4.0/include/linuxcl:rm-rf*.o*.so注意:gcc前面是tab空,j2sdk的目錄根據(jù)自己裝的j2sdk的具體版本來寫,生成的so文件的名字必須是loadLibrary的參數(shù)名前加“l(fā)ib”。
6.exportLD_LIBRARY_PATH=.,由此設置library路徑為當前目錄,這樣java文件才能找到so文件。一般的做法是將so文件copy到本機的LD_LIBRARY_PATH目錄下。
7.執(zhí)行javaweiqiong,打印出結果:“haha---------gointoc!!!”
RMI遠程調用。你查一下這個。
或是webservices
下邊是一個例子,運行server,
再運行client,可以得到對象。
-------------------------------------------------------
import java.rmi.Remote;
import java.rmi.registry.LocateRegistry;
import java.util.Date;
import javax.naming.Context;
import javax.naming.InitialContext;
public class Server {
public static void main(String[] args) throws Exception {
LocateRegistry.createRegistry(2099);
System.setProperty(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.rmi.registry.RegistryContextFactory");
System.setProperty(Context.PROVIDER_URL, "rmi://localhost:2099");
Context ctx = new InitialContext();
ctx.bind("systemStartTime", new RemoteDate());
ctx.close();
while (true)
Thread.sleep(1000);
}
}
class RemoteDate extends Date implements Remote {
}
--------------------
import java.util.Date;
import javax.naming.Context;
import javax.naming.InitialContext;
public class Client {
public static void main(String[] args) throws Exception {
Context ctx = new InitialContext();
Date startTime = (Date) ctx
.lookup("rmi://localhost:2099/systemStartTime");
System.out.println(startTime);
}
}
package org.shirdrn.shell;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.Session;
/**
* 遠程Shell腳本執(zhí)行工具
*
* @author Administrator
*/
public class RemoteShellTool {
private Connection conn;
private String ipAddr;
private String charset = Charset.defaultCharset().toString();
private String userName;
private String password;
public RemoteShellTool(String ipAddr, String userName, String password, String charset) {
this.ipAddr = ipAddr;
this.userName = userName;
this.password = password;
if(charset != null) {
this.charset = charset;
}
}
/**
* 登錄遠程Linux主機
*
* @return
* @throws IOException
*/
public boolean login() throws IOException {
conn = new Connection(ipAddr);
conn.connect(); // 連接
return conn.authenticateWithPassword(userName, password); // 認證
}
/**
* 執(zhí)行Shell腳本或命令
*
* @param cmds 命令行序列
* @return
*/
public String exec(String cmds) {
InputStream in = null;
String result = "";
try {
if (this.login()) {
Session session = conn.openSession(); // 打開一個會話
session.execCommand(cmds);
in = session.getStdout();
result = this.processStdout(in, this.charset);
conn.close();
}
} catch (IOException e1) {
e1.printStackTrace();
}
return result;
}
/**
* 解析流獲取字符串信息
*
* @param in 輸入流對象
* @param charset 字符集
* @return
*/
public String processStdout(InputStream in, String charset) {
byte[] buf = new byte[1024];
StringBuffer sb = new StringBuffer();
try {
while (in.read(buf) != -1) {
sb.append(new String(buf, charset));
}
} catch (IOException e) {
e.printStackTrace();
}
return sb.toString();
}
}
當前名稱:遠程調用代碼java,遠程代碼執(zhí)行
地址分享:http://m.rwnh.cn/article38/phjesp.html
成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站內鏈、微信公眾號、云服務器、ChatGPT、搜索引擎優(yōu)化、靜態(tài)網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經(jīng)允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)