Sokcet的初步理解与使用

我之前一直不明白一个问题(应用层协议是怎么选择tcp还是udp传输协议的?),最近看了socket好像有点明白了.

我的理解是这样的,socket是TCP/IP的封装,TCP/IP本身就是传输层协议,管的就是如何传输,其实当我们在建立socket套接字的时候(socket_create(AF_INET, SOCK_STREAM, SOL_TCP)),这个SOL_TCP其实就是选择了传输层协议是TCP了,那现在又有一个问题了,socket和Http或者websocket协议有啥关系呢,其实这些协议的底层用的都是socket

那socket是个啥东东呢?看两张图片我们就能知道了
在这里插入图片描述
在这里插入图片描述
TCP/IP是传输层协议,主要解决数据如何在网络中传输;而Http是应用层协议,主要解决如何包装数据。

Socket是对TCP/IP协议的封装,Socket本身并不是协议,而是一个调用接口(API),通过Socket,我们才能使用TCP/IP协议。
这就是socket的连接过程
我用php初步演示一下

//Service.php
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($socket, '0.0.0.0', 8888);
socket_listen($socket);
$accept = socket_accept($socket);
$data = socket_read($accept, '1024');
echo $data;
//Client.php
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_connect($socket, '127.0.0.1', 8888);
socket_write($socket, '服务端');
上面的最简单的实现了一下sokect,但是当我们用cli的形式去使用时,会出现个问题,第一个问题,当我执行一次client,客户端和服务端就自动关闭了,这要咋解决呢,其实这个也简单,闲话少说,上代码
<?php
// client.php
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_connect($socket, '127.0.0.1', 8888);
while (true) {
    fwrite(STDOUT, '请输入内容:');
    $in = fgets(STDIN);
    socket_write($socket, $in);
    $data = socket_read($socket, '1024');
    echo  $data;
}
<?php
//Service.php
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($socket, '0.0.0.0', 8888);
socket_listen($socket);
while (true) {
    $accept = socket_accept($socket);
    while (true) {
        $data = socket_read($accept, '1024');
        socket_write($accept, '我是服务端,我给客户端发信息');
        echo $data.PHP_EOL;
    }
}
上面的两段代码就解决了问题,一个客户端连接一个服务端,客户端可以发送任意数据,让服务端接收,服务端也会返回数据,但是又出现了一个问题,如果我开启多个客户端给服务端发送消息,那服务端就只能处理第一个了,那我们接下来要处理现在的问题了,怎么才能让多个客户端连接服务端,正常的发送消息呢?
<?php
// client.php
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_connect($socket, '127.0.0.1', 8888);
while (true) {
    fwrite(STDOUT, '请输入内容:');
    $in = fgets(STDIN);
    socket_write($socket, $in);
    $data = socket_read($socket, '1024');
    echo  $data;
}
<?php
// service.php
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($socket, '0.0.0.0', 8888);
socket_listen($socket);

$sockets[] = $socket;
$write = null;
$except = null;
while (true) {
    $tmp_sockets = $sockets;
    socket_select($tmp_sockets, $write, $except, null);
    foreach ($tmp_sockets as $sock) {
        if ($sock == $socket) {
            $conSock = socket_accept($socket);
            $sockets[] = $conSock;
        } else {
            $data = socket_read($sock, '1024');
            socket_write($sock, '我是服务端,我给客户端发信息');
            echo $data.PHP_EOL;
        }
    }
}
其实这里主要就用了socket_select 这个select是个啥东西呢,就是apache的那个IO多路复用这个机制,看官可以自己测试一下,多开几个client,然后看一下service可不可以接受数据
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值