本文由码农网 –
小峰原创翻译,转载请看清文末的转载要求,欢迎参与我们的付费投稿计划!

Socket介绍

实现客户端与服务端的连接: 

介绍

Socket用于进程间通信。进程间通信通常基于客户端—服务端模型。此时,客户端—服务端是可以彼此交互的应用程序。客户端和服务端之间的交互需要连接。Socket编程负责的就是为应用程序之间建立可进行交互的连接。

在本文中,我们将学习如何用PHP创建一个简单的客户端—服务端。我们还将学习如何客户端应用程序如何发送消息到服务端,以及如何从服务端接受消息。

金沙娱樂城 1

  什么是socket
所谓socket通常也称作”套接字”,用于描述IP地址和端口 ,
是一个通信链的句柄。应用程序通常通过“套接字”先服务器发出请求或者应答网络请求。

  1. 创建TCP服务端的
    ServerSocket

使用代码

目的:开发一个客户端用于发送string消息到服务端,服务端将相同的信息反转后返回给客户端。

PHP服务器

第1步:设置变量,如“主机”和“端口”

$host = "127.0.0.1";
$port = 5353;
// No Timeout 
set_time_limit(0);

端口号可以是1024 -65535之间的任何正整数。

第2步:创建socket

$socket = socket_create(AF_INET, SOCK_STREAM, 0) or die("Could not create socket\n");

第3步:绑定socket到端口和主机

创建的socket资源绑定到IP地址和端口号。

$result = socket_bind($socket, $host, $port) or die("Could not bind to socket\n");

第4步:启动socket监听

在绑定到IP和端口后,服务端开始等待客户端的连接。在没有连接之前它就一直等下去。

$result = socket_listen($socket, 3) or die("Could not set up socket listener\n");

第5步:接受连接

这个函数会接受所建的socket传入的连接请求。在接受来自客户端socket的连接后,该函数返回另一个socket资源,实际上就是负责与相应的客户端socket通信。这里的“$spawn”就是负责与客户端socket通信的socket资源。

$spawn = socket_accept($socket) or die("Could not accept incoming connection\n");

到现在为止,我们已经准备好了服务端socket ,但实际上这个脚本并没有做任何事情。所以为了继续完成上述目标,我们将读取客户端socket消息,然后将接收到的消息反转后发回给客户端socket。

第6步:从客户端socket读取消息

$input = socket_read($spawn, 1024) or die("Could not read input\n");

第7步:反转消息

$output = strrev($input) . "\n";

第8步:发送消息给客户端socket

socket_write($spawn, $output, strlen ($output)) or die("Could not write output\n");

关闭socket

socket_close($spawn);
socket_close($socket);

这就完成了服务端。现在,我们学习如何创建PHP客户端。

PHP客户端

前两个步骤与服务端相同。

第1步:设置变量,如“主机”和“端口”

$host = "127.0.0.1";
$port = 5353;
// No Timeout 
set_time_limit(0);

注:这里的端口和主机应该和服务端中的定义是相同的。

第2步:创建socket

$socket = socket_create(AF_INET, SOCK_STREAM, 0) or die("Could not create socket\n");

第3步:连接到服务端

$result = socket_connect($socket, $host, $port) or die("Could not connect toserver\n");

此时和服务端不同,客户端socket不绑定端口和主机。相反,它连接到服务端socket,等待接受来自客户端socket的连接。这一步建立了客户端socket到服务端socket的连接。

第4步:写入服务端socket

socket_write($socket, $message, strlen($message)) or die("Could not send data to server\n");

金沙娱樂城,在此步骤中,客户端socket的数据被发送到服务端socket。

第5步:阅读来自服务端的响应

$result = socket_read ($socket, 1024) or die("Could not read server response\n");
echo "Reply From Server  :".$result;

第6步:关闭socket

socket_close($socket);

完整的代码

服务端(server.php)

// set some variables
$host = "127.0.0.1";
$port = 25003;
// don't timeout!
set_time_limit(0);
// create socket
$socket = socket_create(AF_INET, SOCK_STREAM, 0) or die("Could not create socket\n");
// bind socket to port
$result = socket_bind($socket, $host, $port) or die("Could not bind to socket\n");
// start listening for connections
$result = socket_listen($socket, 3) or die("Could not set up socket listener\n");

// accept incoming connections
// spawn another socket to handle communication
$spawn = socket_accept($socket) or die("Could not accept incoming connection\n");
// read client input
$input = socket_read($spawn, 1024) or die("Could not read input\n");
// clean up input string
$input = trim($input);
echo "Client Message : ".$input;
// reverse client input and send back
$output = strrev($input) . "\n";
socket_write($spawn, $output, strlen ($output)) or die("Could not write output\n");
// close sockets
socket_close($spawn);
socket_close($socket);

客户端(client.php)

$host    = "127.0.0.1";
$port    = 25003;
$message = "Hello Server";
echo "Message To server :".$message;
// create socket
$socket = socket_create(AF_INET, SOCK_STREAM, 0) or die("Could not create socket\n");
// connect to server
$result = socket_connect($socket, $host, $port) or die("Could not connect to server\n");  
// send string to server
socket_write($socket, $message, strlen($message)) or die("Could not send data to server\n");
// get server response
$result = socket_read ($socket, 1024) or die("Could not read server response\n");
echo "Reply From Server  :".$result;
// close socket
socket_close($socket);

建立上述文件(server.php和client.php)后,执行如下操作:

  1. 复制www目录中的这些文件(假设WAMP),安置于C:\wamp。
  2. 打开Web浏览器,在地址栏中键入localhost 。
  3. 先浏览server.php然后client.php。

  在Internet上的主机一般运行了多个服务软件 ,
同时提供集中服务。每种服务都打开一个Socket , 并绑定一个端口山谷 ,
不同的端口对应于不同的服务。

  ServerSocket
:此类实现服务器套接字。服务器套接字请求通过网络传入,基于该请求执行某些操作,然后可能向请求者返回结果。

许可证

这篇文章,以及任何相关的源代码和文件,是经过The Code Project Open
License (CPOL)许可的。

  tcp->http(可以用来做网站或者相关服务)

  其
accept()方法接受来自客户端的连接请求,并返回一个用于与Client
通信的Socket 对象。此后Server 的对象server 只要向该Socket
对象读写数据,就可以向远程的Client 读写数据。

  udp

下面是一个典型的创建Server端ServerSocket的过程。
  ServerSocket server=null;
  try {
     server=new ServerSocket(4700);
     //创建一个ServerSocket在端口4700监听客户请求
  }catch(IOException e){
     System.out.println(“can not listen to :”+e);
  }
  Socket socket=null;
  try {
    socket=server.accept();
    //accept()是一个阻塞的方法,一旦有客户请求,它就会返回一个Socket对象用于同客户进行交互
  }catch(IOException e){
    System.out.println(“Error:”+e);
  }

Socket连接过程

  以上的程序是Server的典型工作模式,只不过在这里Server只能接收一个请求,接受完后Server就退出了。实际的应用中总是让它不停的循环接收,一旦有客户请求,Server总是会创建一个服务线程来服务新来的客户,而自己继续监听。程序中accept()是一个阻塞函数,所谓阻塞性方法就是说该方法被调用后,将等待客户的请求,直到有一个客户启动并请求连接到相同的端口,然后accept()返回一个对应于客户的socket。这时,客户方和服务方都建立了用于通信的socket,接下来就是由各个socket分别打开各自的输入/输出流。

根据链接启动的方式以及本地套接字要连接的目标 ,
套节字之间的连接过程可以分为三个步骤:

  

1、服务器监听:是服务器端套接字并不定位具体的客户端套接字
, 而是处于等待连接的状态 ,实时监控网络状态。

  ServerSocket
类的构造方法:

2、客户端请求:是指由客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。为此,客户端的套接字必须首先面熟它要连接的服务器的套接字,指出服务器套接字的地址和端口号
, 然后就像服务器端套接字提出连接请求。

ServerSocket()
          创建非绑定服务器套接字。
ServerSocket(int port)
          创建绑定到特定端口的服务器套接字。
ServerSocket(int port, int backlog)
          利用指定的 backlog 创建服务器套接字并将其绑定到指定的本地端口号。
ServerSocket(int port, int backlog, InetAddress bindAddr)
          使用指定的端口、侦听 backlog 和要绑定到的本地 IP 地址创建服务器。

3、连接确认:是指当服务器端套接字监听到或者说接收到客户端套接字的连接请求,他就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客户端
, 一旦客户确认了此描述 ,
连接就建立好了。而服务器端套接字继续处于监听状态,继续接收其他客户端接字的链接请求。

  ServerSocket 类的常用方法

一、测试环境:

 Socket accept()
          侦听并接受到此套接字的连接。
 void bind(SocketAddress endpoint, int backlog)
          将 ServerSocket 绑定到特定地址(IP 地址和端口号)。
 void close()
          关闭此套接字。
 InetAddress getInetAddress()
          返回此服务器套接字的本地地址。
 boolean isBound()
          返回 ServerSocket 的绑定状态。
 boolean isClosed()
          返回 ServerSocket 的关闭状态。

  服务器ip:xxx.xxx.xxx.1

简要代码:

  客户端ip: xxx.xxx.xxx.2

ServerSocket server = new ServerSocket( 有效端口号 );

二 测试过程:

Server client = server.accept(); // 在没有接收到客户端连接请求时,
accept
属于堵塞状态,接收到后继续                                                        //运行。

  客户端服务器将在本机(xxx.xxx.xxx.1)通过socket发送数据到服务端(xxx.xxx.xxx.2)的socket服务器上,服务端收到客户端发送的数据后返回一些给客户端.

if(client!=null){

  System.out.println(“有客户端连接上来了”);

  <?php

}

  //获取tcp协议号吗.

 

  $tcp = getprotobyname;

 2.TCP客户端的Socket

  //建立server端socket ,
创建并返回一个套接字,也称做一个通讯节点.一个典型的网络连接由2个套接字构成
, 一个运行在客户端 , 另一个运行在服务器端.

  Socket
类:此类实现客户端套接字(“套接字”)套接字是两台机器间通信的端点。用于将应用程序和端口连接起来。不同的端口确定连接到服务器的哪项服务上。

  $socket = socket_create(AF_INFT ,
SOCK_STREAM , $tcp);

  创建一个Socket类之后,通过调用 Socket 的getInputStream
方法从服务程序获得输入流传送来的消息;通过调用 getOutputStream
方法获得输出流来发送消息。

  //绑定要监听的ip和端口 ,
这里绑定的ip一定要写局域网ip ,
写成127.0.0.1客户端将无法与服务器端建议连接.

      创建 Socket:

  socket_bind($socket , ‘xxx.xxx.xxx.1’
, 10008);

      下面是一个典型的创建客户端Socket的过程。
   try{
     Socket socket=new
Socket(“127.0.0.1”,4700);
     //127.0.0.1是TCP/IP协议中默认的本机地址
   }catch(IOException e){
     System.out.println(“Error:”+e);
   }

  //监听端口

  这是最简单的在客户端创建一个Socket的一个小程序段,也是使用Socket进行网络通讯的第一步,程序相当简单,在这里不作过多解释了。在后面的程序中会用到该小程序段。

  socket_listen;

     
  注意,在选择端口时,必须小心。每一个端口提供一种特定的服务,只有给出正确的端口,才能获得相应的服务。0~1023的端口号为系统所保留,例如http服务的端口号为80,telnet服务的端口号为21,ftp服务的端口号为23,
所以我们在选择端口号时,最好选择一个大于1023的数以防止发生冲突。

  //初始化一个数据 , 和客户端通信

  在创建socket时如果发生错误,将产生IOException,在程序中必须对之作出处理。所以在创建Socket或ServerSocket是必须捕获或抛出例外。

  $buffer = “connect”;

  常用的构造方法:

  while{

  Socket()
          通过系统默认类型的 SocketImpl 创建未连接套接字
  Socket(InetAddress address, int port)
          创建一个流套接字并将其连接到指定 IP 地址的指定端口号。
  Socket(InetAddress address, int port, InetAddress localAddr, int localPort)
          创建一个套接字并将其连接到指定远程地址上的指定远程端口。
protected Socket(SocketImpl impl)
          使用用户指定的 SocketImpl 创建一个未连接 Socket。
  Socket(String host, int port)
          创建一个流套接字并将其连接到指定主机上的指定端口号。
  Socket(String host, int port, InetAddress localAddr, int localPort)
          创建一个套接字并将其连接到指定远程主机上的指定远程端口。

    //接受客户端请求过来的yigesocket连接

      
其中address、host和port分别是双向连接中另一方的IP地址、主机名和端口号,stream指明socket是流socket还是数据报socket,localPort表示本地主机的端口号,localAddr和bindAddr是本地机器的地址(ServerSocket的主机地址),impl是socket的父类,既可以用来创建serverSocket又可以用来创Socket。count则表示服务端所能支持的最大连接数。例如:
  Socket client = new Socket(“127.0.01.”, 80);
  ServerSocket server = new ServerSocket(80);

    $connection =
socket-accept;

常用的方法:

    if(!connection){

 

      echo “connect faild”;

 void bind(SocketAddress bindpoint)
          将套接字绑定到本地地址。
 void close()
          关闭此套接字。
 void connect(SocketAddress endpoint)
          将此套接字连接到服务器。
 void connect(SocketAddress endpoint, int timeout)
          将此套接字连接到服务器,并指定一个超时值。
 InetAddress getInetAddress()
          返回套接字连接的地址。
 InputStream getInputStream()
          返回此套接字的输入流。
 InetAddress getLocalAddress()
          获取套接字绑定的本地地址。
 OutputStream getOutputStream()
          返回此套接字的输出流。
 SocketAddress getRemoteSocketAddress()
          返回此套接字连接的端点的地址,如果未连接则返回 null
 boolean isBound()
          返回套接字的绑定状态。
 boolean isClosed()
          返回套接字的关闭状态。
 boolean isConnected()
          返回套接字的连接状态。
 boolean isInputShutdown()
          返回是否关闭套接字连接的半读状态 (read-half)。
 boolean isOutputShutdown()
          返回是否关闭套接字连接的半写状态 (write-half)。
 void shutdownInput()
          此套接字的输入流置于“流的末尾”。
 void shutdownOutput()
          禁用此套接字的输出流。
 String toString()
          将此套接字转换为 String

    } else {

 

    echo “Socket connected
\n”;

 简要代码:

    //向客户传递一个信息数据

Socket client = new Socket(“127.0.0.0”,9999);  服务端IP地址与端口号。

   if($buffer != “”){

  查询计算机的ip地址和端口号:

    echo “send data to
client\n”;

  打开命令提示符,输入:
  ipconfig/all   (windows ip configuration
视窗操作系统ip配置)查看当前IP及电脑网络配置;
显示当前电脑ip相关所有信息,包括ip地址、网卡(mac)地址。
  netstat -an ,查看当前所有连接端口;
netstat(在内核中访问网络及相关信息的程序)显示网络连接、路由表和网络接口信息,可以让用户得知目前都有哪些网络连接正在运作。

    socket_write($connection ,
$buffer , “\n”);

 

Author

发表评论

电子邮件地址不会被公开。 必填项已用*标注