PHP 中的 Socket 函数

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/iteye_380/article/details/82680297

Socket 就是一种通信机制,类似于银行、电信这些部门的电话客服部门。打电话时,对方会分配一个坐席代表回答你的问题,客服部门就相当于 Socket 的服务器端,你就相当于客户端。在通话结束前,如果有人想找到和你通话的坐席代表是不可能的,因为你们正在通信,客服部门的电话交换机也不会重复分配。

 

Socket 函数的原型定义如下:

 

SOCKET socket( int af, int type, int protocol);

 

Socket 函数的原型定义如下:

 

af:指定应用程序使用的通信协议的协议族,对于 TCP/IP 协议族该参数置 AF_INET,对于 NUIX 可建立本地 Socket 。

 

type:指定创建的 Socket 类型。有三种可选项。

 

流套接字类型(SOCK_STREAM):最常见类型,基于 TCP 协议。

数据报套接字类型(SOCK_DGRAM):即 UDP 数据报。

原始套接字类型(SOCK_RAW):在 IP 层对套接字进行编程,实际上就是在 IP 层够造自己的 IP 包,然后把这个 IP 包发送出去。

 

protocol:指定应用程序所使用的通信协议。最常用的是 TCP 协议与 UDP 协议。

 

同样,可以把从 TCP/UDP 传输层过来的包抓取过来并进行分析。流套接字和数据报套接字不能完成的任务,可以在原始套接字中得以实现。所有语言提供的 Socket API 都是按照这个原型设计的。

 

提示:Socket 从传输模式上又分为端对端和点对点的连接,流套接字和数据报套接字都属于端对端的连接,因此需要绑定端口号。而原始套接字是基于 IP 协议的,属于点对点的传输模式,是没有端口这个概念的。比如常用的监测网络连接 ping 命令,就是基于 ICMP 协议的,它不存在端口概念。

 

PHP 创建 Socket

 

<?php
$host = '192.168.2.14';
$port = 11109;
set_time_limit(0); //最好在 CLI 模式下运行,保证服务不会超时
//创建 Socket
$socket = socket_create(AF_INET,SOCK_STREAM,SOL_TCP) or die("Could not create socket\n");
//绑定 Socket 到指定地址和端口
$result = socket_bind($socket, $host, $port) or die("Could not bind to socket\n");
//开始监听连接
$result = socket_listen($socket,3) or die("Could not set up socket listener\n");
//接收连接请求并调用另一个子 Socket 处理客户端——服务器间的信息
$spawn = socket_accept($socket) or die("Could not accept incoming connection\n");
//读取客户端输入
$input = socket_read($spawn,1024) or die("Could not read input\n");
//clean up input string
$input = trim($input);
//反转客户端输入数据,返回服务端
$output = strrev($input)."\n";
socket_write($spawn,$output,strlen($output)) or die("Could not write output\n");
//关闭 sockets
socket_close($spawn);
socket_close($socket);
?>

 

PHP 的语言特性和自身定位决定了它只适合做客户端,而不适合做服务器端。因为 Socket  主要面向底层和网络服务开发,一般服务器端都是用 C、Java 等语言实现,这样能更好地操纵底层,对网络服务开发中遇到的问题(如并发、阻塞等)也有完善、成熟的解决方案,而 PHP 显然不适合这种应用场景。

 

实际上,PHP 操作 MySQL 数据库也是通过 Socket  进行的,这正是由于 Socket  屏蔽了底层的协议,使得网络服务之间的互联互通变得简单。

 

展开阅读全文

PHPSOCKET

08-23

没办法,没找到太好的文章!rnLXXXII. Socket functionsrnrnWarning rnThis module is EXPERIMENTAL. That means, that the behaviour of these functions, these function names, in concreto ANYTHING documented here can change in a future release of PHP WITHOUT NOTICE. Be warned, and use this module at your own risk.rn rnrnThe socket extension implements a low-level interface to the socket communication functions, providing the possibility to act as a socket server as well as a client. rnrnThe socket functions described here are part of an extension to PHP which must be enabled at compile time by giving the --enable-sockets option to configure. rnrnFor a more generic client-side socket interface, see fsockopen() and pfsockopen(). rnrnWhen using these functions, it is important to remember that while many of them have identical names to their C counterparts, they often have different declarations. Please be sure to read the descriptions to avoid confusion. rnrnThat said, those unfamiliar with socket programming can still find a lot of useful material in the appropriate Unix man pages, and there is a great deal of tutorial information on socket programming in C on the web, much of which can be applied, with slight modifications, to socket programming in PHP. rnrnExample 1. Socket example: Simple TCP/IP serverrnrnThis example shows a simple talkback server. Change the address and port variables to suit your setup and execute. You may then connect to the server with a command similar to: telnet 192.168.1.53 10000 (where the address and port match your setup). Anything you type will then be output on the server side, and echoed back to you. To disconnect, enter 'quit'. rnrnrn rn rn rnrnrnExample 2. Socket example: Simple TCP/IP clientrnrnThis example shows a simple, one-shot HTTP client. It simply connects to a page, submits a HEAD request, echoes the reply, and exits. rnrnTCP/IP Connection\n";rnrn/* Get the port for the WWW service. */rn$service_port = getservbyname ('www', 'tcp');rnrn/* Get the IP address for the target host. */rn$address = gethostbyname ('www.php.net');rnrn/* Create a TCP/IP socket. */rn$socket = socket (AF_INET, SOCK_STREAM, 0);rnif ($socket < 0) rn echo "socket() failed: reason: " . strerror ($socket) . "\n";rn else rn "socket() successful: " . strerror ($socket) . "\n";rnrnrnecho "Attempting to connect to '$address' on port '$service_port'...";rn$result = connect ($socket, $address, $service_port);rnif ($result < 0) rn echo "connect() failed.\nReason: ($result) " . strerror($result) . "\n";rn else rn echo "OK.\n";rnrnrn$in = "HEAD / HTTP/1.0\r\n\r\n";rn$out = '';rnrnecho "Sending HTTP HEAD request...";rnwrite ($socket, $in, strlen ($in));rnecho "OK.\n";rnrnecho "Reading response:\n\n";rnwhile (read ($socket, $out, 2048)) rn echo $out;rnrnrnecho "Closing socket...";rnclose ($socket);rnecho "OK.\n\n";rn?>rn rn rn rnrnrnTable of Contentsrnaccept_connect — Accepts a connection on a socketrnbind — Binds a name to a socketrnclose — Closes a file descriptorrnconnect — Initiates a connection on a socketrnlisten — Listens for a connection on a socketrnread — Read from a socketrnsocket — Create a socket (endpoint for communication)rnstrerror — Return a string describing a socket errorrnwrite — Write to a socketrnUser Contributed NotesrnSocket functionsrn rn rnpaulwade@greenbush.comrn12-Nov-2000 11:55 rn rn[Editor's note: Not completely correct. Look at the (still not documented) functions (from the PHP source code): rnrnrnint gethostbyaddr(string addr, string &name) rnGiven a human-readable address, sets name to be the host's name rnint gethostbyname(string name, string &addr) rnGiven a hostname, sets addr to be a human-readable version of the host's address rnint getpeername(int fd, string &addr[, int &port]) rnGiven an fd, stores a string representing sa.sin_addr and the value of sa.sin_port into addr and port describing the remote side of a socket rnint getsockname(int fd, string &addr[, int &port]) rnGiven an fd, stores a string representing sa.sin_addr and the value of sa.sin_port into addr and port describing the local side of a socket rnrnThese and other functions will be documented here eventually] rnrnI filed a wishlist bug because I do not see any way to get the IP address of the client. Until this is added I would use caution in implementing servers with PHP4. You can control access to selected ports at the OS level with linux. It might be wise to limit port access to specific machines or subnets.rn rn rntom.anheyer@berlinonline.dern09-Feb-2001 03:49 rn rnThere are many undocumentated functions yet: rnrnresource fd_alloc(void) rnAllocates a file descriptor set rnrnbool fd_dealloc(void) rnDe-allocates a file descriptor set rnrnbool fd_set(int fd, resource set) rnAdds a file descriptor to a set rnrnbool fd_clear(int fd, resource set) rnClears a file descriptor from a set rnrnbool fd_isset(int fd, resource set) rnChecks to see if a file descriptor is set within the file descrirptor set rnrnvoid fd_zero(resource set) rnClears a file descriptor set rnrnint select(int max_fd, resource readfds, resource writefds, resource exceptfds, int tv_sec, int tv_usec) rnRuns the select() system call on the sets mentioned with a timeout specified by tv_sec and tv_usec rnrnint open_listen_sock(int port) rnOpens a socket on port to accept connections rnrnbool set_nonblock(int fd) rnSets nonblocking mode for file descriptor fd rnrnint getsockname(int fd, string &addr[, int &port]) rnGiven an fd, stores a string representing sa.sin_addr and the value of sa.sin_port into addr and port describing the local side of a socket rnrnint gethostbyname(string name, string &addr) rnGiven a hostname, sets addr to be a human-readable version of the host's address rnrnint getpeername(int fd, string &addr[, int &port]) rnGiven an fd, stores a string representing sa.sin_addr and the value of sa.sin_port into addr and port describing the remote side of a socket rnrnint gethostbyaddr(string addr, string &name) rnGiven a human-readable address, sets name to be the host's name rnrnresource build_iovec(int num_vectors [, int ...]) rnBuilds a 'struct iovec' for use with sendmsg, recvmsg, writev, and readv rnFirst parameter is number of vectors, each additional parameter is the rnlength of the vector to create. rnrnstring fetch_iovec(resource iovec_id, int iovec_position) rnReturns the data held in the iovec specified by iovec_id[iovec_position] rnrnbool set_iovec(resource iovec_id, int iovec_position, string new_val) rnSets the data held in iovec_id[iovec_position] to new_val rnrnbool add_iovec(resource iovec_id, int iov_len) rnAdds a new vector to the scatter/gather array rnrnbool delete_iovec(resource iovec_id, int iov_pos) rnDeletes a vector from an array of vectors rnrnbool free_iovec(resource iovec_id) rnFrees the iovec specified by iovec_id rnrnint readv(int fd, resource iovec_id) rnReads from an fd, using the scatter-gather array defined by iovec_id rnrnint writev(int fd, resource iovec_id) rnWrites to a file descriptor, fd, using the scatter-gather array defined by iovec_id rnrnint recv(int fd, string buf, int len, int flags) rnReceives data from a connected socket rnMay be used with SOCK_DGRAM sockets. rnrnint send(int fd, string buf, int len, int flags) rnSends data to a connected socket rnMay be used with SOCK_DGRAM sockets. rnrnint recvfrom(int fd, string &buf, int len, int flags, string &name [, int &port]) rnReceives data from a socket, connected or not rnrnint sendto(int fd, string buf, int len, int flags, string addr [, int port]) rnSends a message to a socket, whether it is connected or not rnrnint recvmsg(int fd, resource iovec, array &control, int &controllen, int &flags, string &addr [, int &port]) rnUsed to receive messages on a socket, whether connection-oriented or not rnrnint sendmsg(int fd, resource iovec, int flags, string addr [, int port]) rnSends a message to a socket, regardless of whether it is connection-oriented or not rnrnint getsockopt(int fd, int level, int optname, array|int &optval) rnGets socket options for the socket rnIf optname is SO_LINGER, optval is returned as an array with members rn"l_onoff" and "l_linger", otherwise it is an integer. rnrnint setsockopt(int fd, int level, int optname, int|array optval) rnSets socket options for the socket rnIf optname is SO_LINGER, optval is expected to be an array rnwith members "l_onoff" and "l_linger", otherwise it should be an integer. rnrnint socketpair(int domain, int type, int protocol, array &fds) rnCreates a pair of indistinguishable sockets and stores them in fds. rnrnint shutdown(int fd, int how) rnShuts down a socket for receiving, sending, or both.rn rn rn11-Apr-2001 04:31 rn rni've tested the 'one-shot http client' with some sites (yahoo, google, etc) and always had the same problem: read() won't return 0 when finished, rather a negative number. thus the read line would be rnrnwhile (read ($socket, $out, 2048) >= 0) rnrnthis happens with php 4.0.4pl1.rn rn rnnospam@1111-internet.comrn20-Apr-2001 04:05 rn rnI also had some difficulties getting my http client to work properly when it came to reading response data from the socket (I'm using PHP 4.0.4pl1). The <=0 return value from the "read" call was only part of the problem. rnrnI managed to get it working as follows: rnrn0) rn rn$read.=$read_segment; rn// test - even this didn't work rnecho $read_segment; rn// test 2 - this actually did work, but it's relatively useless rnecho "1234 $read_segment"; rn rnclose ($socket); rnreturn $read; rn*/ rnrn// this seems to work reliably rnwhile (read($socket, $read_array[], 2048)>0) rnclose ($socket); rnreturn implode("", $read_array); rn rnrn?> rnrnThe scalar $read_segment method was logically sound, but it failed in some odd ways. Something to do with the "&buffer" concept perhaps (see the "read" function page)? I couldn't find any documentation that explains the difference between "&buffer" behavior vs. normal string variable behavior...rn rn rnmartinREMOVE@humany.REMOVE.comrn09-May-2001 06:43 rn rnSocket support isn't available on windows yet :-( Hopefully soon thorn rn rnjudeman@yahoo.comrn04-Jun-2001 10:49 rn rnAfter several hours of working with sockets in an attempt to do UDP broadcasting, I thought a little help was in order for anyone else looking to do something similar, since it uses a number of those "undocumented" functions. Here's how I did it: rnrn 论坛

没有更多推荐了,返回首页