一、Socket 简介1、socket只不过是一个数据结构。2、使用这个socket数据结构去开始一个客户端和服务器之间的会话。3、服务器是一直在监听准备产生一个新的会话。当一个客户端连接服务器,它就打开服务器正在进行监听的一个端口进行会话。4、服务器端接受客户端的连接请求,那么就进行一次循环。现在这个客户端就能够发送信息到服务器,服务器也能发送信息给客户端。
二、Socket 变量产生一个Socket,你需要三个变量:一个协议、一个socket类型和一个公共协议类型。
1、协议
AF_INET //产生socket的协议,使用TCP或UDP来传输,用在IPv4的地址
AF_INET6 //产生socket的协议,使用TCP或UDP来传输,用在IPv6的地址
AF_UNIX //本地协议,使用在Unix和Linux系统上,它很少使用,一般都是当客户端和服务器在同一台机器上的时候使用
2、Socket类型
SOCK_STREAM //这个协议是按照顺序的、可靠的、数据完整的基于字节流的连接。这是一个使用最多的socket类型,这个socket是使用TCP来进行传输。
SOCK_DGRAM //这个协议是无连接的、固定长度的传输调用。该协议是不可靠的,使用UDP来进行它的连接。
SOCK_SEQPACKET //这个协议是双线路的、可靠的连接,发送固定长度的数据包进行传输。必须把这个包完整的接受才能进行读取。
SOCK_RAW //这个socket类型提供单一的网络访问,这个socket类型使用ICMP公共协议。(ping、traceroute使用该协议)
SOCK_RDM //这个类型是很少使用的,在大部分的操作系统上没有实现,它是提供给数据链路层使用,不保证数据包顺序
3、公共协议
ICMP //互联网控制消息协议,主要使用在网关和主机上,用来检查网络状况和报告错误信息
UDP //用户数据报文协议,它是一个无连接,不可靠的传输协议
TCP //传输控制协议,这是一个使用最多的可靠的公共协议,它能保证数据包能够到达接受者那儿,如果在传输过程中发生错误,那么它将重新发送出错数据包。
三、Socket函数1、socket_create作用:产生一个socket,相当于产生一个socket的数据结构用法:socket_create ( int domain, int type, int protocol )参数:domain,协议;type,类型;protocol,公共协议返回:socket resource on success, or FALSE on error
2、socket_bind作用:把socket绑定在一个IP地址和端口上用法:socket_bind ( resource socket, string address [, int port] )参数:socket,socket resource;address,ip地址;port,端口返回:Boolean
3、socket_accept作用:接受一个Socket连接用法:socket_accept ( resource socket )参数:socket,socket resource返回:Returns a new socket resource on success, or FALSE on error.
4、socket_connect()作用:开始一个socket连接用法:socket_connect ( resource socket, string address [, int port] )参数:socket,socket resource;address,ip地址;port,端口返回:Boolean
5、socket_listen作用:监听由指定socket的所有连接用法:socket_listen ( resource socket [, int backlog] )参数:socket,socket resource;返回:Boolean
6、socket_read作用:读取指定长度的数据用法:socket_read ( resource socket, int length [, int type] )参数:socket,socket resource;length,字符长度;type,PHP_BINARY_READ |PHP_NORMAL_READ返回:string
7、socket_write作用:写数据到socket缓存用法:socket_write ( resource socket, string buffer [, int length] )参数:socket,socket resource;buffer,字符;length,字符长度;返回:Boolean
8、socket_send()作用:这个函数发送数据到已连接的socket用法:socket_send ( resource socket, string buf, int len, int flags )参数:socket,socket resource;buf,字符;len,字符长度;返回:Boolean
9、socket_last_error作用:获取当前socket的最后错误代码用法:socket_last_error ( [resource socket] )参数:socket,socket resource;返回:int
10、socket_strerror作用:返回指定错误号的详细错误用法:socket_strerror ( int errno )参数:errno,socket_last_error no;返回:string
11、socket_close作用:关闭一个socket资源用法:socket_close ( [resource socket] )参数:socket,socket resource;返回:null
四、使用说明确认打开socket方法a、编辑php.ini文件,去掉 extension=php_sockets.dll 前面的注释:b、代码来加载扩展库
if(!extension_loaded('sockets')) {
if(strtoupper(substr(PHP_OS, 0, 3)) == "WIN") {
dl('php_sockets.dll');
}else{
dl('sockets.so');
} }
五、总结
一个socket就像一个插头它提供了两个进程间通信的方式。一般来说它允许你在任意未被使用的端口进行接收或发送信息。
那么怎样使用sockets呢socket 服务端的编写为了使问题不至于太复杂这里我们写一个简单的例子步骤如下
在指定的IP和端口创建一个socket 使用socket_create()和socket_bind()
socket监听 使用socket_listen() 等待来自客户端的链接
使用socket_accept() 从socket读取数据
使用socket_read() 输出数据后
关闭socket 使用socket_close()
六、案例
//服务端===server.php====
// Server
// 设置错误处理
error_reporting (E_ALL);
// 设置运行时间
set_time_limit (0);
// 起用缓冲
ob_implicit_flush ();
$ip = "127.0.0.1"; // IP地址
$port = 1000; // 端口号
$socket = socket_create (AF_INET, SOCK_STREAM, SOL_TCP); // 创建一个SOCKET
if ($socket)
echo "socket_create() successed!\n";
else
echo "socket_create() failed:".socket_strerror ($socket)."\n";
$bind = socket_bind ($socket, $ip, $port); // 绑定一个SOCKET
if ($bind)
echo "socket_bind() successed!\n";
else
echo "socket_bind() failed:".socket_strerror ($bind)."\n";
$listen = socket_listen ($socket); // 间听SOCKET
if ($listen)
echo "socket_listen() successed!\n";
else
echo "socket_listen() failed:".socket_strerror ($listen)."\n";
while (true)
{
$msg = socket_accept ($socket); // 接受一个SOCKET
if (!$msg)
{
echo "socket_accept() failed:".socket_strerror ($msg)."\n";
break;
}
$welcome = "Welcome to PHP Server!\n";
socket_write ($msg, $welcome, strlen ($welcome));
while (true)
{
$command = strtoupper (trim (socket_read ($msg, 1024)));
if (!$command)
{
break;
}
else if ($command == 'EXIT')
{
$writer = 'Thinks You Bye-Bye!';
}
else
{
$writer = 'The Server Accept your write:'.$command;
}
/*switch ($command)
{
case "HELLO":
$writer = "Hello Everybody!";
break;
case "QUIT":
$writer = "Bye-Bye";
break;
case "HELP":
$writer = "HELLO\tQUIT\tHELP";
break;
default:
$writer = "Error Command!";
}*/
socket_write ($msg, $writer, strlen ($writer));
if ($command == "EXIT"){ break;}
}
socket_close ($msg);
}
socket_close ($socket); // 关闭SOCKET
//客户端===client.php======
// Client
// 设置错误处理
error_reporting (E_ALL);
// 设置处理时间
set_time_limit (0);
$ip = "127.0.0.1"; // IP 地址
$port = 1000; // 端口号
$socket = socket_create (AF_INET, SOCK_STREAM, SOL_TCP); // 创建一个SOCKET
if ($socket)
echo "socket_create() successed!\n";
else
echo "socket_create() failed:".socket_strerror ($socket)."\n";
$conn = socket_connect ($socket, $ip, $port); // 建立SOCKET的连接
if ($conn)
echo "Success to connection![".$ip.":".$port."]\n";
else
echo "socket_connect() failed:".socket_strerror ($conn)."\n";
echo socket_read ($socket, 1024);
$stdin = fopen ('php://stdin', 'r');
while (true)
{
$command = trim (fgets ($stdin, 1024));
socket_write ($socket, $command, strlen ($command));
$msg = trim (socket_read ($socket, 1024));
echo $msg."\n";
if ($msg == "Thinks You Bye-Bye!")
break;
}
fclose ($stdin);
socket_close ($socket);
服务端(图例):
客户端(图例):