// char 1-byte character PHP::Pack:C // byte 1-byte unsigned integer PHP::Pack:C // word 2-byte unsigned integer PHP::Pack:v // short 2-byte signed integer PHP::Pack:s (System Native Style) // unsigned 4-byte unsigned integer PHP::Pack:V // int 4-byte signed integer PHP::Pack:l (System Native Style) // float 4-byte float PHP::Pack:f (System Native Style)
<?php
// ENUMERATIONS FOR PACKET TYPES; define('ISP_ISI', 1);
// Bit Flags For IS_ISI->Flags define('ISF_RES_0', 1); # bit 0 : spare define('ISF_RES_1', 2); # bit 1 : spare define('ISF_LOCAL', 4); # bit 2 : guest or single player define('ISF_MSO_COLS', 8); # bit 3 : keep colours in MSO text define('ISF_NLP', 16);# bit 4 : receive NLP packets define('ISF_MCI', 32);# bit 5 : receive MCI packets
$IS_ISI = pack( 'CCCCvvCCva16a16', 44, # byte Size 44; ISP_ISI, # byte Type Always ISP_ISI; $ReqI, # byte ReqI If Not 0, ISP_VER Sent; 0, # byte Zero Always Zero (0); $UDPPort, # word UDPPort Port for UDP Replies $Flags, # word Flags Bit Flags for Options $Sp0, # byte Sp0 Spare $Prefix, # byte Prefix Special Host Message Prefix Character $Interval,# word Interval Time in ms Between NLP or MCI (0 = No Packets Sent) $Admin, # chr16 Admin Password (If Set in LFS) $IName # chr16 IName A Short Name for Your Program );
There are some pretty cool stuff in the comments for the socket_select function.
<?php php $port = 9050; # create a streaming socket, of type TCP/IP $sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); # set the option to reuse the port socket_set_option($sock, SOL_SOCKET, SO_REUSEADDR, 1); # "bind" the socket to the address to "localhost", on port $port # so this means that all connections on this port are now our resposibility to send/recv data, disconnect, etc.. socket_bind($sock, 0, $port); # start listen for connections socket_listen($sock); # create a list of all the clients that will be connected to us.. # add the listening socket to this list $clients = array($sock); while (true) { # create a copy, so $clients doesn't get modified by socket_select() $read = $clients; # get a list of all the clients that have data to be read from # if there are no clients with data, go to next iteration if (socket_select($read, $write = NULL, $except = NULL, 0) < 1) continue; # check if there is a client trying to connect if (in_array($sock, $read)) { # accept the client, and add him to the $clients array $clients[] = $newsock = socket_accept($sock); # send the client a welcome message socket_write($newsock, "no noobs, but ill make an exception :)\n". "There are ".(count($clients) - 1)." client(s) connected to the server\n"); socket_getpeername($newsock, $ip); echo "New client connected: {$ip}\n"; # remove the listening socket from the clients-with-data array $key = array_search($sock, $read); unset($read[$key]); } # loop through all the clients that have data to read from foreach ($read as $read_sock) { # read until newline or 1024 bytes # socket_read while show errors when the client is disconnected, so silence the error messages $data = @socket_read($read_sock, 1024, PHP_NORMAL_READ); # check if the client is disconnected if ($data === false) { # remove client for $clients array $key = array_search($read_sock, $clients); unset($clients[$key]); echo "client disconnected.\n"; # continue to the next client to read from, if any continue; } # trim off the trailing/beginning white spaces $data = trim($data); # check if there is any data after trimming off the spaces if (!empty($data)) { # send this to all the clients in the $clients array (except the first one, which is a listening socket) foreach ($clients as $send_sock) { # if its the listening sock or the client that we got the message from, go to the next one in the list if ($send_sock == $sock || $send_sock == $read_sock) continue; # write the message to the client -- add a newline character to the end of the message socket_write($send_sock, $data."\n"); } # end of broadcast foreach } } # end of reading foreach } # close the listening socket socket_close($sock); ?>