基于Socket的SOA通信服务

TCP/IP Socket

1.1  Socket简介

   socket中文名叫套接字,应用程序通过套接字向网络发送请求或者应答请求,最早是unix上的一套网络通信标准,已被广泛移植到其他平台,在internet上一般运行着多个服务软件,同时提供了几种服务,每种服务都打开一个socket并绑定到端口上,不同的端口对应与不同的服务进程。socket实质上提供了进程通信的端点,网络上的两个程序通过一个双向的通讯链路实现数据的交换,这个双向链路的一端称为一个socket

 

1.2  socket分类

1.2.1原始式套接字

该接口允许对较低层次协议,如IP直接访问,可以接收本机网卡上的数据包与数据帧,对监听网络流量和分析很有用。

1.2.2流式套接字

提供了一个面向连接,可靠的数据传输服务,数据无差错,无重复的发送,且按发送顺序接收,对应使用的是TCP协议。

1.2.3数据报式套接字

无连接服务。数据包以独立包形势被发送,不提供无差错保证,数据可能丢失或重复,并且接收顺序无序,其实它对应使用的是udp协议

1.3 如何使用socket

1.3.1  Socket API

 

1.3.2  ServerSocket API

 

1.3.3  服务端创建步骤

1 建立一个服务器socket,绑定指定端口并开始监听

2 使用accept()方法阻塞等待监听

3 建立输入与输出流

4 在已有的协议上产生绘画

5 使用close关闭流的socket

1.3.4  客户端创建步骤

1 建立客户端socket连接,指定服务器的位置及端口号

2 得到socket读写流

3 利用流按照一定的协议对socket进行读写操作

4 使用close()关闭socket操作

1.3.5通信流程

 

如上图所示服务端创建一个套接子服务,创建一个阻塞式的服务等待连接,客户端向服务端发动连接请求,建立连接,客户端向服务端发送请求,服务端接收到请求以后给客户端返回数据,客户端关闭套接字,通信结束。

1.3.6 1v1字符串通信事例程序

服务端

public class ServerSocketS {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket=new ServerSocket(8888);
Socket accept = serverSocket.accept();
InputStream inputStream = accept.getInputStream();
//字节流转换为字符流
BufferedReader buf=
new BufferedReader(new InputStreamReader(inputStream));
String flow=null;
while((flow=buf.readLine())!=null){
System.out.println(flow);
}
   }
}

客户端

public class ClientSocket {
  public static void main(String[] args) throws UnknownHostException, IOException {
  Socket socket=new Socket("127.0.0.1", 8888);
  OutputStream outputStream = socket.getOutputStream();
  PrintWriter printWriter=new PrintWriter(outputStream);
  printWriter.write("你好");
  printWriter.flush();
  printWriter.close();  
 }
}

1.3.7 1v1对象通信事例程序

通过socket做对象传输就是通过对象序列化的方式进行传输的

 

服务器端

public class ServerSocketObject {
public static void main(String[] args) throws IOException, ClassNotFoundException {
ServerSocket serverSocket=new ServerSocket(8787);
Socket accept = serverSocket.accept();
    //阻塞等待客户端输入
InputStream inputStream = accept.getInputStream();
OutputStream outputStream = accept.getOutputStream();
ObjectInputStream in=new ObjectInputStream(inputStream);
User u=(User) in.readObject();
System.out.println(u.getName());
System.out.println(u.getAge());
PrintWriter writer=new PrintWriter(outputStream);
writer.write("成功登陆");
writer.flush();
writer.close();
inputStream.close();
outputStream.close();
serverSocket.close();
}
}

客户端

public class ClientSocketObject {
public static void main(String[] args) throws IOException {
Socket socket=new Socket("127.0.0.1", 8787);
OutputStream outputStream = socket.getOutputStream();
InputStream inputStream = socket.getInputStream();
User user=new User();
user.setName("张三");
user.setAge(18);
ObjectOutputStream out=new ObjectOutputStream(outputStream);
out.writeObject(user);
BufferedReader reader
=new BufferedReader(new InputStreamReader(inputStream));
String str=null;
while((str=reader.readLine())!=null){
System.out.println(str);
}
inputStream.close();
reader.close();
out.close();
socket.close();
}
}

对象类

public class User implements Serializable {
private String name;
private int age;
public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}

1.3.8 1vN对象通信实例

 

在实际的工作中,往往是客户端发起一个连接与客户端建立了链接之后,服务端启动一个连接线程,然后又等待下一次通信的接入。

服务端

public class ServerSocketObject {
public static void main(String[] args) throws IOException, ClassNotFoundException {
//服务器端一直开着 每获取到一个连接的情况下开启一个服务线程
ServerSocket serverSocket=new ServerSocket(8787);
Socket socket =null;
    int num=0;
    while(true){
    socket=serverSocket.accept();
        SocketThread socketThread=new SocketThread(socket);
        socketThread.start();
        num++;
        System.out.println("第"+num+"个连接客户");
    }
}
}


public class SocketThread extends Thread{
Socket socket=null;
public SocketThread(Socket socket){
this.socket=socket;
}

public void run(){
try{
  //阻塞等待客户端输入
InputStream inputStream = socket.getInputStream();
OutputStream outputStream = socket.getOutputStream();
ObjectInputStream in=new ObjectInputStream(inputStream);
User u=(User) in.readObject();
System.out.println(u.getName());
System.out.println(u.getAge());
PrintWriter writer=new PrintWriter(outputStream);
writer.write("成功登陆");
writer.flush();
writer.close();
inputStream.close();
outputStream.close();
}catch(Exception e){
e.printStackTrace();
}
}
}

客户端

public class ClientSocketObject {
public static void main(String[] args) throws IOException {
Socket socket=new Socket("127.0.0.1", 8787);
OutputStream outputStream = socket.getOutputStream();
InputStream inputStream = socket.getInputStream();
User user=new User();
user.setName("李四");
user.setAge(18);
ObjectOutputStream out=new ObjectOutputStream(outputStream);
out.writeObject(user);
BufferedReader reader
=new BufferedReader(new InputStreamReader(inputStream));
String str=null;
while((str=reader.readLine())!=null){
System.out.println(str);
}
inputStream.close();
reader.close();
out.close();
socket.close();
}
}

实体类

public class User implements Serializable {
private String name;
private int age;
public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}
}

UDPSocket

2.1 Socket简介

 

   不需要建立连接,不需要完全可靠的数据传输,简单不可靠,及时,快速

客户端要向外发送数据,必须用datagramPacket封装数据报,进行发送。


2.2 DatagramSocket API

 

2.3 通信实例

2.3.1 服务端

public class UapServer {
  public static void main(String[] args) throws Exception {
DatagramSocket socket=new DatagramSocket(8888);
//接收客户端请求
byte[] buf=new byte[1024];
DatagramPacket dp=new DatagramPacket(buf,buf.length);
socket.receive(dp);
String text=new String(buf,0,dp.getLength());
System.out.println("客户端数据:"+text);
//服务端给客户端返回数据
String tex="你好我是服务器";
byte[] br=tex.getBytes();
SocketAddress socketAddress = dp.getSocketAddress();
DatagramPacket send=new DatagramPacket(br,br.length,socketAddress);
socket.send(send);
socket.close();
  }
}

2.3.2 客户端

public class UapClient {
public static void main(String[] args) throws Exception {
String st="你好我是客户端";
byte[] by=st.getBytes();
InetAddress addre = InetAddress.getByName("localhost");
DatagramSocket socket=new DatagramSocket();
DatagramPacket datagramPacket=
new DatagramPacket(by, by.length,addre,8888);
socket.send(datagramPacket);
byte[] bs=new byte[1024];
DatagramPacket packet=new DatagramPacket(bs, bs.length);
socket.receive(packet);
String s=new String(bs,0,packet.getLength());
System.out.println(s);
socket.close();
}
}

URL&URLConnection

3.1概述

java 提供了两个类,在这两个类里封装了大部分 Web 相关的各种操作。这两个类是 URL 类和 URLConnection 类。

3.2 URL

java.net.URL 类定义了一个统一的资源定位器,它是指向互联网“资源”的指针。可以定

位互联网上的资源。并且在定位的资源存在的情况下,允许以流的方式读取该资源。这些资源可能是一个简单的文件,也可能是一个目录,甚至可以是一个复杂的对象,比如搜索引擎。

JDK 6.0 URL 类提供 6 种构造方法,在这里我们介绍常用的两种,第一种是

URL(String spec),它只有一个构造参数,这个构造方法表示用指定的字符串创建一个 URL

象,这个字符串呢它是一个 URL 地址,比如 http://localhost:8080/index.html,我们就可以

根据这个 URL 地址字符串的表示形式创建一个 URL 对象。第二种构造方法有四个构造参数,protocol 表示网络协议,host 表示主机名,port 表示端口号,file 表示资源路径。这个构造方法会使用指定的网络协议,主机名,端口号和资源路径创建一个 URL 对象。

try {      

URL url = new URL("http://localhost:8080/index.jsp");  

System.out.println("此 URL 的主机是: " + url.getHost());  

System.out.println("此 URL 的协议是: " + url.getProtocol());

System.out.println("此 URL 的端口是: " + url.getPort());   

System.out.println("此 URL 的路径是: " + url.getPath());

} catch (Exception e) {

e.printStackTrace();

}  


 

3.3 URLConnection

URLConnection 类代表应用程序和 URL 之间的通信连接。此类的实例可以通过调用 URL

象的openConnection()方法获得,URLConnection对象可用于读取或写入 URL对象引用的资源。我们要向创建一个程序和 URL 之间的连接,也就是说我们要创建一个 URLConnection 对象,那么我们首先要创建一个 URL 对象 ,然后在 URL 对象上调用 openConnection()方法来创建一个连接对象,也就是说 URL 对象的 openConnection()方法会返回一个 URLConnection 对象。因此呢,URLConnection 对象就只有一个构造方法,构造参数就是一个 URL 对象,接下来,下面我们要了解的是 URLConnection 类的常用方法。

URL url = new URL("http://www.jb-aptech.com.cn");

URLConnection con = url.openConnection();

System.out.println("使用的 URL 是:" + con.getURL());

System.out.println("内容类型:" + con.getContentType());

System.out.println("内容长度:" + con.getContentLength());

System.out.println("最后修改:" + con.getLastModified());

System.out.println("超时设置:" + con.getConnectTimeout()); 


猜你喜欢

转载自blog.csdn.net/worn_xiao/article/details/80216438