关于socket的使用体验

本文介绍了Socket的基本概念及其作为TCP/IP协议族与应用层之间的桥梁作用。通过实例代码演示了如何利用PHP实现简单的客户端与服务器端通信,包括创建套接字、绑定地址、监听连接及收发数据等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

因工作需要接触了socket,但socket是什么呢?很多人未必能说清楚,以下是我对socket的粗浅理解。

首先看一张图:

         Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。这段是别人对socket的总结,我认为socket是一个载体,它让TCP/UDP这些抽象的协议找到了一个可以具体使用的方法,通过socket就可以对这些协议进行使用。

        了解socket的概念后,我们要尝试去使用它,我写了两个接口,一个是客户端的 client.php(发送和接收数据) 一个是服务器端的server.php(处理客户端的请求)

原理如下


通过这两个接口就可以实现客户端和服务器端的信息交流, 当然这是最简单的,一个网友告诉我,如果要用socket去做网络编程,那必须要考虑多线程,但是php是不支持多线程的。网上找到了一下解决办法,一般是用其他语言实现,具体可以参考PHP的swoole扩展 http://www.swoole.com/


下面是完整代码:

服务器端:

<?php
/**
*  @package :  class.tool
*  @classID :  Server.class.php
*  @author  :  钟华宝
*  @date    :  2014-08-28
*  服务器端通信类
*/

class ServerSocket
{
    private $server_port = '10051';//通信端口
    private  $address = 'http://192.168.2.119/';//通信地址

    /**
    *  构造函数
    *  @access public
    */
    public function __construct()
    {
    
    }
    
    /**
    *  析构函数
    *  @access public
    */
    public function __destruct()
    {
    
    }
    
    /**
    *  服务端接收和发送信息函数
    *  @access public
    */
    public function server_Socket()
    {
        error_reporting(E_ALL);
        set_time_limit(0);
    
       //创建一个套接字(通讯节点)(指定协议,套接字类型,具体协议)
       if( ($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === false) {
            //echo "socket_create() failed :reason:" . socket_strerror(socket_last_error());
            return false;
       }
        //绑定
        if (socket_bind($sock, $this->address, $this->server_port) === false) {
            //echo "socket_bind() failed :reason:" . socket_strerror(socket_last_error($sock));
            return false;
        }       
       
      
       
       //监听
       if(socket_listen($sock, 5) === false){
            echo "socket_bind() failed :reason:" . socket_strerror(socket_last_error($sock));
            return false;
       }
        
       //不断循环
       do {
          //得到链接
          if (($msgsock = socket_accept($sock)) === false) {
                echo "socket_accepty() failed :reason:".socket_strerror(socket_last_error($sock)) . "\n";
                return false;
          }
          
          $msg = 'server test\n';
          
          //发送数据
          socket_write($msgsock, $msg, strlen($msg));
//socket_write($msgsock, $msg, strlen($msg));
        
          
          //接收数据
          $buf = socket_read($msgsock, 8192);
          
          
          
          $talkback = "received message:$buf<br />";
          if (false === socket_write($msgsock, $talkback, strlen($talkback))) {
               echo "socket_write() failed reason:" . socket_strerror(socket_last_error($sock));
               return false;
          }
          else{
              echo 'send success\n';
          }
          socket_close($msgsock);
          
       } while(true);
       socket_close($sock);
    }

}

$ser = new ServerSocket();
$ser->server_Socket();

?>


客户端:

<?php

/**
*  @package :  class.tool
*  @classID :  Client.class.php
*  @author  :  钟华宝
*  @date    :  2014-08-28
*  客户端通信类
*/

class ClientSocket
{
    private  $server_port = '10051';//通信端口
    private  $address = 'http://192.168.2.119/';//通信地址

    /**
    *  构造函数
    *  @access public
    */
    public function __construct()
    {
    
    }
    
    /**
    *  析构函数
    *  @access public
    */
    public function __destruct()
    {
    
    }

    /**
    *  服务端接收和发送信息函数    
    *  @access public
    */
    public function client_Socket($Arr, $cat_type = '', $type = '')
    {
        
        //判断参数是否符合条件
        if(empty($Arr)||!is_array($Arr)||$cat_type == ''){
            return false;    
        }
        else{
            //将参数组装成数组
              $content = array(
                  'arr' => $Arr,
                  'cat_type'=> $cat_type,
                  'type' => $type
            );
        }
        $content = '111111111111';
        
        //创建一个套接字(通讯节点)(指定协议,套接字类型,具体协议)
        $socket = socket_create(AF_INET,SOCK_STREAM,SOL_TCP);
        if ($socket === false) {
            // echo "socket_create() failed: reason: " . socket_strerror(socket_last_error());
            return false;
        }
        //开启一个套接字连接
        $result = socket_connect($socket,$this->address,$this->server_port);
        if ($result === false) {
            //echo "socket_connect() failed.\nReason: ($result) " . socket_strerror(socket_last_error($socket));
            return false;
        }     
        //发送数据
        socket_write($socket,$content,strlen($content));
        
        //读取指定长度的数据
        while ($out = socket_read($socket, 8192)) {
            echo $out;
        }
        
        //关闭一个socket资源
        socket_close($socket);
    }
    
}



?>

windows 下服务器端需要在cli模式是执行,有可能cli模式下php.ini文件载入的不一样




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值