菜单

Swoole 网络通讯协议,固定邯郸。

2019年3月9日 - Java

互连网通讯进度中,大概会出现分包和合包的意况。具体情状如https://wiki.swoole.com/wiki/page/484.html文档所讲的。这里测试了下固定包头的协议。示例代码如下

互连网通讯,网络通信协议

 

1.解包封装的情势 

一 概述

communicationPack.php

<?php
//对数据信息封装
function packData($sendData,$packModel){
    return pack($packModel, strlen($sendData)).$sendData;
}

//解包
function unpackData($rcvData,$packModel){
    $length = $packModel=='N'?4:2;
    return substr($rcvData,$length);
}

1.网络模型

OSI(Open System
Interconnection,开放式系统互联)模型,是对网络系统结构的牢笼,将互连网分为七层:应用层、表示层、会话层、传输层、互联网层、数据链路层、物理层。

2.服务端 tcpServer.php

2.IP协议

网络层协议,规定了在网络上规定与寻找计算机的规则。

<?php
require_once 'communicationPack.php';
$packModel = 'N';
//创建Server对象,监听 127.0.0.1:9501端口
$serv = new swoole_server("127.0.0.1", 9501);
$serv->set(array(
    'open_length_check' => true,
    'package_max_length' => 2000000,
    'package_length_type' => $packModel, //see php pack()
    'package_length_offset' => 0,
    'package_body_offset' => $packModel=='N'?4:2,
));
//监听连接进入事件
$serv->on('connect', function ($serv, $fd) {
    echo "Client: Connect.\n";
});

//监听数据接收事件
$serv->on('receive', function ($serv, $fd, $from_id, $data) use($packModel){
    echo "#{$serv->worker_id}>> received length=" . strlen($data) ."data=".$data. "}\n";
    $data = unpackData($data,$packModel);
    $returnStr = "Server: ".$data;
    $serv->send($fd, packData($returnStr,$packModel));
});

//监听连接关闭事件
$serv->on('close', function ($serv, $fd) {
    echo "Client: Close.\n";
});

//启动服务器
$serv->start();

3.TCP协议

传输层的一种多少传输协议,数据传输前透过“二遍握手”建立连接,然后再发送数据,适用于对数码准确性须求较高的情况,由于数量传输前供给建立连接,传输速度较慢。

运营服务端

4.UDP协议

传输层的一种多少传输协议,数据传输前不供给树立连接,适用于对数码准确性必要不高的动静,传输数据较快,一般聊天新闻都由此该协议传输。

图片 1

5.HTTP协议

HTTP协议属于应用层协议,为操作系统或互联网应用程序提供访问互联网服务的接口。

 

6.端口port

当数码到达总括机后,为了找到对象应用程序,为每二个应用程序分配了四个平头值,取值0-65535,这些整数值就是端口,从中能够看来,端口代表了电脑上多少个应用程序,保险数据准确到达约定的程序。3个端口无法同时被多个应用程序占用,一个应用程序甘休现在,端口不会立马放飞,有3个内部存款和储蓄器延迟占有的时刻,那几个时间一般不够长。端口、0-1023曾经被系统应用程序及任何应用程序占用,程序设计时防止选用那一个限制的端口。

3 客户端 tcpClient.php

7.套接字Socket

套接字是数码发送与接受的工具。发送者通过套接字发送数据,接受者通过套接字监听内定的端口获取数据。

8.无论采取TCP协议,照旧UDP磋商,数据都只可以以字节格局发送。

<?php
require_once 'communicationPack.php';
$packModel = 'N';
$client = new swoole_client(SWOOLE_SOCK_TCP);
$client->set(array(
    'open_length_check'     => true,
    'package_length_type'   => $packModel,
    'package_length_offset' => 0,       //第N个字节是包长度的值
    'package_body_offset'   => $packModel=='N'?4:2,       //第几个字节开始计算长度
    'package_max_length'    => 2000000,  //协议最大长度
));
//连接到服务器
if (!$client->connect('127.0.0.1', 9501, 0.5))
{
    die("connect failed.");
}
//向服务器发送数据
//数据协议
$sendData = "test123";
$sendData = packData($sendData,$packModel);
if (!$client->send($sendData))
{
    die("send failed.");
}
//从服务器接收数据
$data = $client->recv();
if (!$data)
{

    die("recv failed.");
}
echo unpackData($data,$packModel);
//关闭连接
$client->close();

二 TCP程序设计

1.关门通过Socket获取的输入流恐怕输出流将关门Socket。

2.由此Socket获取的出口流输出了结后务必关闭,不然另一端对应的输入流将阻塞。由于通过输出流对象关闭输出流时,同时关闭Socket对象,将造成另一端无法获得相应Socket的靶子,因而不得不通过Socket下的艺术shutdownOutput关闭输出流。

 然后开发银行客户端

3.客户端的相似步骤: 

Socket socket=new Socket(String host,int port);//创建客户端Socket,发送与接收数据,需要指明服务器IP与端口
OutputStream os=socket.getOutputStream();//获取输出流,向服务器发送数据
..........
os.flush();
socket.shutdownOutput();//关闭输出流,防止服务器端阻塞

InputStream is=socket.getInputStream();//获取输入流,输入流包含服务器的反馈信息
............

socket.close();//关闭socket,同时关闭输入与输出流

图片 2

4.服务器的貌似步骤:

ServerSocket server=new ServerSocket(int port);//建立服务器端套接字,指定监听端口
Socket socket=server.accept();//获取访问客户端的Socket,阻塞线程
InputStream is=socket.getInputStream();//获取输入流,其中包含客户端发送的数据
.............

OutputStream os=socket.getOutputStream();//获取输出流,向客户端反馈信息
..............
os.flush();
os.shutdownOutput();

server.close();

劳务端会打字与印刷

5.Demo

图片 3

客户端

package com.javase.networkCommunication.tcp.demo02;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

public class ImgClient {

    public static void main(String[] args) throws UnknownHostException, IOException {
        Socket socket = new Socket("192.168.146.1", 10007);
        FileInputStream is = new FileInputStream("Files/1.jpg");
        OutputStream os = socket.getOutputStream();
        byte[] buf = new byte[1024];// 先将数据读取到缓冲区,比频繁的从硬盘读取速度快
        int length = 0;
        while ((length = is.read(buf)) != -1) {
            os.write(buf, 0, length);
        }
        os.flush();
        socket.shutdownOutput();// 如果输出流不关闭,服务端对应的输入流会阻塞

        InputStream replyIs = socket.getInputStream();//不会阻塞线程
        byte[] buf01 = new byte[1024];
        int length01 = replyIs.read(buf01);
        String reply = new String(buf01, 0, length01);
        System.out.println(reply);

        is.close();
        socket.close();
    }

}

pack N是将数据转成了无符号三十七位的数字,那些刚好长度是6个字节,所以设定

服务器

package com.javase.networkCommunication.tcp.demo02;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

import org.junit.Test;

public class ImgServer {

    @Test
    public void test01() throws IOException {
        ServerSocket serverSocket = new ServerSocket(10007);
        Socket socket = serverSocket.accept();// 线程阻塞,等待请求
        System.out.println("hostAddress=" + socket.getInetAddress().getHostAddress());
        InputStream is = socket.getInputStream();
        FileOutputStream os = new FileOutputStream("Files/2.jpg");
        System.out.println(1);
        byte[] buf = new byte[1024];
        int length = 0;
        System.out.println(2);
        int count = 3;
        while ((length = is.read(buf)) != -1) {
            os.write(buf, 0, length);
            System.out.println(count++);
        }
        os.flush();
        os.close();
        System.out.println("图片上传结束");

        /*PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
        out.write("success");*/
        OutputStream out = socket.getOutputStream();
        out.write("success".getBytes());
        out.flush();
        socket.shutdownOutput();
        System.out.println("响应数据已发出");

        serverSocket.close();
    }

}
package_body_offset=4

三 UDP程序设计

 

1.多少处理情势

UDP商业事务以数据包的款式发送数据,每一个包的最大值64k。

2.发送数据的形似步骤:

DatagramSocket socket=new DatagramSocket();//创建数据报套接字用于发送数据
//DUP协议采用数据包分段发送数据,因此需要建立数据包,在数据包中指明目的地IP与端口
DatagramPacket packet= DatagramPacket(byte buf[], int offset, int length,InetAddress address, int port);
socket.send(packet);

3.接收数据的一般步骤:

DatagramSocket socket=new DatagramSocket(int port);//创建监听指定端口的数据报套接字
DatagramPacket packet=new DatagramPacket(byte buf[], int length);
socket.receive(packet);

http://www.bkjia.com/Javabc/1216566.htmlwww.bkjia.comtruehttp://www.bkjia.com/Javabc/1216566.htmlTechArticle网络通信,网络通信协议 一 概述 1.网络模型
OSI(Open System
Interconnection,开放式系统互联)模型,是对网络系统结构的回顾,将网络分为七层…

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图