swoole_server->send [编辑本页]

向客户端发送数据,函数原型:

bool swoole_server->send(int $fd, string $data, int $extraData = 0);
  • $data,发送的数据,TCP协议最大不得超过2M,可修改 buffer_output_size 改变允许发送的最大包长度
  • UDP协议不得超过65507UDP包头占8字节, IP包头占20字节,65535-28 = 65507
  • UDP服务器使用$fd保存客户端IP,$extraData保存server_fdport
  • 发送成功会返回true
  • 发送失败会返回false,调用$server->getLastError()方法可以得到失败的错误码

TCP服务器

  • send操作具有原子性,多个进程同时调用send向同一个TCP连接发送数据,不会发生数据混杂
  • 如果要发送超过2M的数据,可以将数据写入临时文件,然后通过sendfile接口进行发送
  • 通过设置 buffer_output_size 参数可以修改发送长度的限制
  • 在发送超过8K的数据时,底层会启用Worker进程的共享内存,需要进行一次Mutex->lock操作
  • Worker进程的管道缓存区已满时,发送8K数据将启用临时文件存储
  • 不需要关心客户端的带宽,底层会自动监听可写,将数据逐步发送给客户端
  • 如果连续向同一个客户端发送大量数据,可能会导致Socket内存缓存区塞满,底层会立即返回false,应用程序可以调整socket_buffer_size设置,或 将数据保存到磁盘,等待客户端收完已发送的数据后再进行发送

TCP客户端发送数据,不需要$extraData参数

UDP服务器

  • send操作会直接在Worker进程内发送数据包,不会再经过主进程转发
  • 如果在onReceive后立即向客户端发送数据,可以不传$extraData
  • 如果向其他UDP客户端发送数据,必须要传入$extraData
  • 在外网服务中发送超过64K的数据会分成多个传输单元进行发送,如果其中一个单元丢包,会导致整个包被丢弃。所以外网服务,建议发送1.5K以下的数据包

  • 啊啊

    $fd 从哪里能够获取到

  • 安达英司

    receive回调中,你看下面的事件列表。

  • swoole粉

    关于send这块,给客户端进行socket传输的时候。需要考虑丢包粘包等传输问题吗。

  • Pader

    1.7.5 在 FreeBSD 10 上,使用 send 发送字符串只要稍微有些长,就会发送失败,控制台输出:[2014-09-27 13:45:45] WARN swFactoryProcess_finish: sendto to reactor failed. Error: Message too long [40]

  • swoole使用者

    $serv->send($self_fd, $self_msg);
    $serv->send($other_fd, $other_msg); $self_msg,$other_msg 都是10kb左右的数据,发送的时候,客服端接收到的数据都是$other_msg呢?当我sleep(1);的时候就可以了,请问这是什么问题导致的呢?

  • 史高雄

    我以API的形式提供服务,用户请求的数据长度很可能会超过2M,如果以文件的形式发送,又会改变接口协议,不现实,这种情况该怎么处理呢?求指教

  • 史高雄

    以send和sendfile发送到客户端的内容,用户接受到的内容形式是一样的吗

  • 比尔

    send中的Data尝试发送bool或是位数小于6位的字符串和数字,浏览器通通得不到返回值。使用的是1.7.8-stable版本。data 长度大于等于6位即可,这是为什么?

  • 陈晓生

    为什么一调用sendfile进程就退出呢

  • 陈宇哲

    PHP Warning: swoole_server::send(): cannot send to client in task worker with SWOOLE_BASE mode. 我是使用 Cygwin 配置的

  • Su孤兒zzzzzzzJ

    我用send会提示 WARN swReactorProcess_send2client: send[0] failed, session#5 has expired.

  • 学习swoole

    怎么给所有人发送消息呢?

  • YY

    为什么我用send向客户端发消息,客户端只能接受到两次 $data = 123456; $serv->send( $fd, $data ); $serv->send( $fd, $data ); $serv->send( $fd, $data ); $serv->send( $fd, $data );

  • Clive

    我也发现这个问题,为什么$client->recv() 只能收到2次,我发了3次,2次以下都可以,3次及以上被阻塞了

  • YY

    有些发送的合到一条里面被接收的

  • Clive

    应该不是包合并的问题,我客户端配置了这3个以eof结尾的 'package_eof'=>DB_EOF, 'open_eof_split' => true, 'open_eof_check' => true,

  • 刘钢Gary

    send失败 $server->getLastError() 为0是什么情况