server2.php
<?php
error_reporting(E_ALL);
//连接不超时
set_time_limit(0);
$ip = "192.168.1.2";
$port = "9588";
/*
+-------------------------------
* @socket通信整个过程
+-------------------------------
* @socket_create
* @socket_bind
* @socket_listen
* @socket_accept
* @socket_read
* @socket_write
* @socket_close
* @socket_set_option
* @socket_strerror()
+--------------------------------
*/
/*---------------- 以下操作都是手册上的 -------------------*/
echo "start create server.... \n";
//1 - create
$server = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($server < 0 ){
echo "server create failed ". socket_strerror($server) ."\n";
} else {
echo "server create successfully \n";
}
//2 - options
if (!socket_set_option($server, SOL_SOCKET, SO_REUSEADDR, 1)){
echo "reuseaddr set failed". socket_last_error() ."\m";
}
$linger = array("l_linger" => 1, "l_onoff" => 1);
socket_set_option($server, SOL_SOCKET, SO_LINGER, $linger);
socket_set_nonblock($server);
//3 - bind
$b = socket_bind($server, $ip, $port);
if ($b < 0 ){
echo "server bind failed " . socket_strerror($b). "\n";
} else {
echo "server bind successfully at ". $ip ." : ". $port. "\n";
}
//4 - listen
$l = socket_listen($server, 4);
if ($l < 0 ){
echo "server listen failed " .socket_strerror($l). "\n";
} else {
echo "server listen successfully \n";
}
$count = 0; //连接计数
$clients = array($server); //受监控的sockets
while(true){
$read = $clients;
$write = $clients;
$except = NULL;
// 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($s = socket_select($read, $write, $except, 0) < 1 ){
continue;
}
if (in_array($server, $read)){
$newSock = socket_accept($server);
if ($newSock < 0) {
echo "\n socket_accept failed" .socket_strerror($server) ."\n";
break;
} else {
echo "\n accept a connection from " .$newSock." \n";
//add in read watch array
$clients[] = $newSock;
echo "\n total connected clients: ". (count($clients) - 1) ."\n";
//write msg to clients
$msg1 = "[msg from server]greetings from server";
socket_write($newSock, $msg1, strlen($msg1));
$newSockInfo = socket_getpeername($newSock, $peer_ip, $peer_port);
echo "\n connected client with ip : ". $peer_ip . " port:". $peer_port ."\n";
$msg2 = "[msg from server]2nd msg from server: close your phone! ";
socket_write($newSock, $msg2, strlen($msg2));
}
//remove server
$key = array_search($server, $read); //find key by value
unset($read[$key]);
}
//all clients
foreach($read as $read_sock){
//p1: cannot read
$data = socket_read($read_sock, 8192);
if( $data == false ){
$key = array_search($read_sock, $read);
unset($read[$key]);
echo "\n client ".$read_sock." is offline \n";
continue;
}
$data = trim($data);
$readInfo = socket_getpeername($read_sock, $r_ip, $r_port);
echo "\n [msg from " . $r_ip . ":" . $r_port . "] ".$data ."\n";
//p2: can read but data is empty
//broadcast
if (!empty($data)){
foreach($clients as $send_sock){
if ($send_sock == $server || $send_sock == $read_sock) {
continue;
}
$send_data = "[" . $r_ip . ":" . $r_port . "]" . $data . "\n";
socket_write($send_sock, $send_data, strlen($send_data));
}
}
} //end of foreach
}
socket_close($server);
echo "server close successfully \n";
?>
Client2.h
//
// Client2.h
// MySocket
//
// Created by sj on 14/06/2018.
// Copyright © 2018 Apple. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <string.h>
#import <stdio.h>
#import <sys/socket.h>
#import <arpa/inet.h>
#import <netinet/in.h>
#import <unistd.h>
@interface Client2 : NSObject
#define IP "192.168.1.2"
#define PORT 9588
@property CFSocketRef client;
@property BOOL isOnline;
-(void) create;
-(void) sendData :(NSString *)s;
-(void) readData;
-(void) test;
@end
Client2.m
//
// Client2.m
// MySocket
//
// Created by sj on 14/06/2018.
// Copyright © 2018 Apple. All rights reserved.
//
#import "Client2.h"
@implementation Client2
- (void)create {
//1
CFSocketContext ctx = {0, (__bridge void*)self, NULL, NULL, NULL};
_client = CFSocketCreate(kCFAllocatorDefault,
PF_INET,
SOCK_STREAM,
IPPROTO_TCP,
kCFSocketConnectCallBack,
TCPConnectionCallBack,
&ctx);
if (_client != nil) {
NSLog(@"\n client create successfully \n");
//3
struct sockaddr_in addr4;
memset(&addr4, 0, sizeof(addr4));
addr4.sin_len = sizeof(addr4);
addr4.sin_addr.s_addr = inet_addr(IP);
addr4.sin_port = htons(PORT);
addr4.sin_family = PF_INET;
CFDataRef address = CFDataCreate(kCFAllocatorDefault, (UInt8 *)&addr4, sizeof(addr4));
CFSocketError con = CFSocketConnectToAddress(_client, address, -1);
CFRunLoopRef c = CFRunLoopGetCurrent();
CFRunLoopSourceRef src = CFSocketCreateRunLoopSource(kCFAllocatorDefault, _client, 0);
CFRunLoopAddSource(c, src, kCFRunLoopDefaultMode);
CFRelease(src);
CFRunLoopRun();
//这个不可靠
if (con == kCFSocketSuccess) {
NSLog(@"client connect successfully \n"); //
[self readData];
NSLog(@"非阻塞,可读");
} else if (con == kCFSocketError) {
NSLog(@"client connect error \n");
} else if (con == kCFSocketTimeout) {
NSLog(@"client connect time out \n");
}
}
}
void TCPConnectionCallBack (CFSocketRef socket, CFSocketCallBackType type, CFDataRef address, const void *data, void *info){
if (data !=NULL) {
NSLog(@"client connect failed! \n");
return;
}
Client2 *c = (__bridge Client2*)info;
;
;
}
- (void)sendData:(NSString *)s{
char *buf = [s UTF8String];
send(CFSocketGetNative(_client), buf, strlen(buf) + 1, 0);
}
- (void)readData{
@autoreleasepool {
char buf[2048];
while (recv(CFSocketGetNative(_client), buf, sizeof(buf), 0)) {
NSLog(@"\n%@\n", [NSString stringWithUTF8String:buf]);
}
}
}
//entry
-(void) test {
NSThread *n = [[NSThread alloc]initWithTarget:self selector:@selector(create) object:nil];
[n start];
}
@end