前面主要讲了tcp得server和client的业务处理,tcp有三次握手,有连接的概览,而UDP服务器与TCP服务器不同,UDP没有连接的概念。启动Server后,客户端无需Connect,直接可以向Server监听的端口发送数据包。server 接受数据的事件为onPacket, 发送给client的方法变成sendto

udp Server

<?php
/**
* Created by PhpStorm.
* User: yangyi
* Date: 2016/12/7
* Time: 18:02
*/ //创建Server对象,监听 127.0.0.1:9503端口,类型为SWOOLE_SOCK_UDP
$serv = new Swoole\Server("127.0.0.1", 9503, SWOOLE_BASE, SWOOLE_SOCK_UDP); //监听数据发送事件
$serv->on('Packet', function ($serv, $data, $clientInfo) {
//发送给客户端 用sendto
$serv->sendto($clientInfo['address'], $clientInfo['port'], "Server ".$data);
var_dump($data);
}); //启动服务器
$serv->start();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

udp client

<?php
/**
* Created by PhpStorm.
* User: yangyi
* Date: 2016/12/7
* Time: 18:02
*/ $client = new Swoole\Client(SWOOLE_SOCK_UDP);
$client->connect('127.0.0.1', 9503, 1);
$i = 0;
while ($i < 1000) {
$client->send($i."\n");
$message = $client->recv();
echo "Get Message From Server:{$message}\n";
$i++;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

上面server启动之后,会启动一个进程,默认不是4个,就一个主进程,来处理数据。

pstree |grep server.php
| | \--= 87143 yangyi php udp_server.php
  • 1
  • 2
  • 1
  • 2

然后接受客户端的数据的监听的方法变成了Packet了,而不是Receive。发送数据给client 的方法为sendto。需要客户端的地址和端口。这点和tcp不一样,没有fd的概念。

$serv->sendto($clientInfo['address'], $clientInfo['port'], "something");

如果业务请求量很大,一个worker 肯定是不够的,我们利用多个task worker的方式来改写下server。

<?php
/**
* Created by PhpStorm.
* User: yangyi
* Date: 2016/12/7
* Time: 18:02
*/ //创建Server对象,监听 127.0.0.1:9503端口,类型为SWOOLE_SOCK_UDP
$serv = new Swoole\Server("127.0.0.1", 9503, SWOOLE_BASE, SWOOLE_SOCK_UDP); $serv->set([
'worker_num' => 4, # 4个worker
'task_worker_num' => 4, # 4个task
'deamonize' => false,
]); //监听数据发送事件
$serv->on('Packet', function ($serv, $data, $clientInfo) {
$serv->sendto($clientInfo['address'], $clientInfo['port'], "Server ".$data);
var_dump($clientInfo, $data);
//把任务丢给task
$serv->task($data);
}); $serv->on('Task', function ($serv, $task_id, $from_id, $data) {
echo "This Task {$task_id} from Worker {$from_id}\n";
echo "Data: {$data}\n";
//模拟慢io查询、
for($i = 0 ; $i < 2 ; $i ++ ) {
sleep(1);
echo "Task {$task_id} Handle {$i} times...\n";
}
//return 数据 给 Finish
return "Task {$task_id}'s result";
}); $serv->on('Finish', function ($serv,$task_id, $data) {
echo "Task {$task_id} finish\n";
echo "Result: {$data}\n";
}); //启动服务器
$serv->start();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46

再看下进程

$ pstree |grep server.php
| | \-+= 88426 501 php udp_server.php #master
| | \-+- 88427 501 php udp_server.php #manager
| | |--- 88428 501 php udp_server.php #worker、task
| | |--- 88429 501 php udp_server.php
| | |--- 88430 501 php udp_server.php
| | |--- 88431 501 php udp_server.php
| | |--- 88432 501 php udp_server.php
| | |--- 88433 501 php udp_server.php
| | |--- 88434 501 php udp_server.php
| | \--- 88435 501 php udp_server.php
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

发现启动了8个work进程和一个manager进程一个master进程

这样就完成了一个多worker的udp server。

启动server,再启动client。

server

$ php udp_server.php

#打印udp的地址和ip
/Users/yangyi/www/bestPHP/swoole/udp_server.php:22:
array(3) {
'server_socket' =>
int(4)
'address' =>
string(9) "127.0.0.1"
'port' =>
int(55182)
}
#打印客户端发来的数据
/Users/yangyi/www/bestPHP/swoole/udp_server.php:22:
string(2) "0" #task启动
This Task 0 from Worker 1
Data: 0 Task 0 Handle 0 times...
Task 0 Handle 1 times... #task finish
Task 0 finish
Result: Task 0's result
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

client

$ php udp_client.php
#获取server发回的数据
Get Message From Server:Server 0
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

参考资料:

http://wiki.swoole.com/wiki/page/477.html

 
 

swoole深入学习 3. upd Server和udp Client的更多相关文章

  1. swoole深入学习 2. tcp Server和tcp Client

    这节来学习Swoole最基础的Server和Client.会通过创建一个tcp Server来讲解. server <?php class Server { private $serv; pub ...

  2. TCP/UDP Socket调试工具提供了TCP Server,TCP Client,UDP Server,UDP Client,UDP Group 五种Socket调试方案。

    一.TCP通信测试: 1)   创建TCP Server: 选中左方的TCP Server, 然后点击”创建”按钮,软件弹出监听端口输入框 输入监听端口后,即创建了一个在指定端口上进行监听的TCP S ...

  3. swoole深入学习 8. 协程 转

    版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/yangyi2083334/article/ ...

  4. Socket 学习(三).4 UDP 穿透 客户端与客户端连接

    效果图: 使用方法:  先 修改WinClient\bin\Debug  下面的 ip.ini,写上 服务器 IP地址. 客户端 与 客户端 通讯 之前 ,点击发送打洞消息 按钮,然后过一会再发送消息 ...

  5. Swoole 简单学习(2)

    Swoole 简单学习(2) swoole之tcp服务器: //创建tcp服务器new swoole_server(string $host,int $port,int $mode=SWOOLE_PR ...

  6. 使用JAVA NIO实现的UDP client和server

    //////////////////////////////////////////////////////////////////////////////////////////////////// ...

  7. UDP client,UDP server, TCP server, TCP client

    UDP server import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocke ...

  8. Swoole 入门学习(二)

    Swoole 入门学习 swoole 之 定时器 循环触发:swoole_timer_tick    (和js的setintval类似) 参数1:int $after_time_ms 指定时间[毫秒] ...

  9. 在socket的server端处理client端发来的数据

    一.楔子 最近做了一个需求遇到一个坑,归结成一个小问题,其实就是在socket的server端处理client端发来的数据的问题,现将这个问题总结一下,本文将数据在server端以字典的形式存储. 另 ...

随机推荐

  1. Linux内核驱动之GPIO子系统(一)GPIO的使用【转】

    转自:http://blog.csdn.net/tommy_wxie/article/details/9427047 一 概述 Linux内核中gpio是最简单,最常用的资源(和 interrupt  ...

  2. oracle 存储过程 clob 字段 调试

    clob 没法直接赋值调试,可以新建一个存储过程,赋值给clob字段,然后调试

  3. oracle 分区 查询

    显示数据库所有分区表的信息:DBA_PART_TABLES 显示当前用户可访问的所有分区表信息:ALL_PART_TABLES 显示当前用户所有分区表的信息:USER_PART_TABLES 显示表分 ...

  4. python在windows下安装

    打开python官方网站:https://www.python.org/downloads/ 点击下载 翻到底下的file目录下 选择对应的32,64位系统进行安装 一般来说选择Windows x86 ...

  5. xcode 8 清除无用的打印

    OS_ACTIVITY_MODE     disable 虽然模拟器这样写能屏蔽掉无用的打印,但是在真机测试的时候什么都不会打印  Nslog 也打印不出来  , 这时候就要点掉 OS_ACTIVIT ...

  6. Sudo的用法和Visudo设置

    身为程序员,你可以活在一个没有Windows的世界,当你离不开Unix(Linux,Mac...).而在Unix下面,你离不开terminal,离不开sudo. 你知道sudo command,然后输 ...

  7. openj 4004 01背包问题求方案数

    #include<iostream> #include<cstring> #include<cstdio> using namespace std; #define ...

  8. Python decorator

    1.编写无参数的decorator Python的 decorator 本质上就是一个高阶函数,它接收一个函数作为参数,然后,返回一个新函数. 使用 decorator 用Python提供的 @ 语法 ...

  9. pychrame更换默认以unittest执行或取消单元测试框架执行

    选择某个测试框架运行脚本 File-> Settings -> Tools -> Python Integrated Tools -> Default test runner ...

  10. 【C++ Primer | 19】嵌套类、局部类

    嵌套类 #include <iostream> using namespace std; class c1 { public: int a; void foo(); class c2 { ...