菜单

Swoole 网络通讯协议,固定岳阳。

2019年2月26日 - Php

互联网通讯进程中,大概会油不过生分包和合包的情况。具体景况如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个端口不能同时被多少个应用程序占用,一个应用程序结束之后,端口不会立马释放,有八个内部存款和储蓄器延迟占有的年华,这几个时刻一般十分的短。端口、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是将数据转成了无符号三十二人的数字,那些刚好长度是五个字节,所以设定

服务器

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地图