分布式系统中进程通信的理解

同步和异步同步通信

同步:发送进程与接收进程在每一个信息上都是同步的,这时,send和receive都是阻塞操作,每次发出一个receive后,发送进程都会一直阻塞,知道发送了相应的receive操作为止,每次发送了一个receive时,都会一直阻塞直到消息到达为止。
异步:send操作是非阻塞的,只要消息被复制到本地缓冲区,发送进程就可继续其他的操作,而receive是具有阻塞和非阻塞两种形式,非阻塞的接收进程可在发送receive操作后,可继续执行其他操作,但是后台要提供一个缓冲区,必须通过轮询或是中断独立接收缓冲区已满的通知

套接字

套接字提供进程间通信的一个端点(UDP和TCP都是用套接字抽象)
进程间的通信是在两个进程各自的一个套接字之间传送一个消息,对接收消息的进程它的套接字必须绑定一个计算机英特网地址和一个端口。

UDP数据包通信

数据报的数据包
包含消息的字节数组  |   消息长度  |  英特网地址  | 端口号
UDP数据包的javaAPI DatagramPacket和DatagramSocket这两个类提供数据包通信
DatagramPacket:实例可以在进程之间传送,此时其中一个进程发送,另一个进程接收。
DatagramSocket:该类支持套接字发送和接收UDP数据报,提供一个以端口号位参数的构造函数,用于使用特定的端口的进程。

UDP客户发送一个消息到服务器并获得一个应答

import java.net.*;
import java.io.*;
public class UDPClient{
    public static void main(String args[]){
        //args字符数组传递了内容和主机名
        DatagramSocket aSocket = null;
        try{
            aSocket = new DatagramSocket();
            byte[] m = args[0].getBytes();
            InetAddress aHost = InetAddress.getByName(args[1]);
            int serverPort = 6789;
            DatagramPacket request = new DatagramPacket(m, args[0].length, aHost, serverPort);
            aSocket.send(request);
            byte[] buffer = new byte[1000];
            DatagramPacket reply = new DatagramPacket(buffer, buffer.length);
            aSocket.receive(reply);
            System.out.println("reply" + new String(reply.getData()));
        }catch(SocketException e){
            System.out.println("Socket:" + e.getMessage());
        }catch(IOException e){
            System.out.println("IO:" + e.getMessage());
        }finally{
            if(aSocket != null){
                aSocket.close();
            }
        }
    }
}

UDP服务器不断的接收请求并将它发回给客户

import java.net.*;
import java.io.*;
public class UDPServer{
    public static void main(String args[]){
        DatagramSocket aSocket = null;
        try{
            aSocket = new DatagramSocket(6789);
            byte[] buffer = new byte[1000];
            while(true){
                DatagramPacket request = new DatagramPacket(buffer, buffer.length,);
                aSocket.receive(request);
                DatagramPacket reply = new DatagramPcaket(request.getData(), reuqest.getLength(), request.getAdderss(), request.getPort());
                aSocket.send(reply);
            }catch(SocketException e){
                System.out.println("Socket:" + e.getMessage());
            }catch(IOException e){
                System.out.println("IO:" + e.getMessage());
            }finally{
                if(aSocket != null){
                    aSocket.close();
                }
            }
        }
    }
}

TCP流通信

数据项的匹配问题:
两个进程需要对在流上传送数据的内容要达成一致。否则会造成数据类型的解释出错或是由于流中数据的不足而造成的阻塞

阻塞:
写入流的数据保存在目的地的套接字的队列中,当程序试图从输入通道读取数据时候将从队列中获取数据或是一直阻塞到有数据获取为止。

线程:
当服务器连接的时候,它通常需要创建一个新的线程用于新的客户通信。为每一个用户使用单独的线程的好处是服务器在等待输入的时候能阻塞而不会延误其他的用户。

TCP流的JAVA API
ServerSocket:服务器使用该类在服务器端口上创建一个套接字,以便监听客户的connect请求
accept()方法从队列中获得一个connect请求,如果队列为空,就会阻塞,直到有消息到达队列为止。执行accept的结果是获得一个Socket实例—该套接字用于访问与客户的通信流
Socket:该类可供连接的一对进程使用。客户使用构造函数创建函数创建套接字。

TCP客户与服务建立连接,发送请求并接收应答

import java.net.*
import java.io.*
public class TCPClient{
    public static void main(String args[]){
        Socket s = null;
        try{
            int serverPort = 7890;
            s = new Socket(args[1], serverPort);
            DataInputStream in = new DataInputStream(s.getInputStream());
            DataOutputStream out = new DataOutStream(s.getOutputStream());
            out.writeUTF(args[0]);
            String data = in.read();
            System.out.println("reveive:" + data);
        }catch(UnkwonHostException e){

        }catch(EOFEXCException e){\

        }catch(IOException e){

        }finally{
            if(s != null){
                try{
                    s.close();
                }catch(IOException e){}
            }
        }
    }
}

TCP服务器为每一个客户建立连接,然后回应客户的请求

import java.net.*;
import java.io.*;
public class TCPServer{
    public static void main(String args[]){
        try{
            int serverPort = 7890;
            ServerSocket listenSocket = new ServerSocket(servePort);
            while(true){
                Socket clientSocket = listenSocket.accetp();
                Connection c = new Connection(cilentSocket);
            }           
        }catch(IOException e){}
    }
}
class Connection extends Thread{
    DataInputStram in;
    DataOutputStream out;
    Socket client;
    public Connection(Socket aClientSocket){
        try{
            client = aClientSocket;
            in = new DataInputStream(clientSocket.getInputStream());
            out = new DataOutputStream(cilentSocket.getOutputStream());
            this.start();
        }catch(IOException e){}
    }
    public voidrun(){
        try{
            String data = in.readUTF();
            out.writeUTF(data);
        }cach(EOFException e){

        }catch(IOException e){

        }finally{
            try{
                cilentSocket()
            }
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值