您的位置:首页 > 移动开发 > IOS开发

ios编程笔记:CFSocket

2016-04-18 10:56 232 查看
ios编程笔记:CFSocket(服务端)

主要函数:

第一步:创建

CFSocketRef CFSocketCreate(

CFAllocatorRef allocator, //内存分配类型一般为默认KCFAllocatorDefault

SInt32 protocolFamily, //协议族,一般为Ipv4:PF_INET,(Ipv6,PF_INET6)

SInt32 socketType, //套接字类型TCP:SOCK_STREAM

UDP:SOCK_DGRAM

SInt32 protocol, //套接字协议TCP:IPPROTO_TCP

UDP:IPPROTO_UDP;

CFOptionFlags callBackTypes, //回调事件触发类型

Enum CFSocketCallBACKType{

KCFSocketNoCallBack = 0,

KCFSocketReadCallBack =1,

KCFSocketAcceptCallBack = 2,(常用)

KCFSocketDtatCallBack = 3,

KCFSocketConnectCallBack = 4,

KCFSocketWriteCallBack = 8

}

CFSocketCallBack callout, // 触发时调用的函数

Const CFSocketContext *context // 用户定义数据指针

)

假设_socket = CFSocketCreate(….);

第二步:初始化

int yes = 1 ;

setsocketopt(

CFSocketGetNative(_socket),//返回系统原生套接字,补齐缺省

SOL_SOCKET,

SO_REUSEADDR,

(void*)&yes,

sizeof(yes)

) //对socket进行定义设置

第三步:地址

uint16_t port = 12345;

struct sockaddr_in addr4; // 定义监听地址以及端口

memset(&addr4 , 0, sizeof (addr4));

addr4.sin_len = sizeof (addr4);

addr4.sin_family = AF_INET;

addr4.sin_port =htons(port)

addr4.sin_addr.s_addr = htonl(INADDR_ANY);

CFData Ref address =CFDataCreate(

kCFAllocatorDefault,

(UInt8 *)& addr4,

sizeof (addr4),

)

int rst = CFSocketSetAddress(_socket ,&addr4);

//将设置数据设入socket

If ( rst != KCFSocketSuccess )

{…}

第四步:执行

CFRunLoopRef cfrl = CFRunLoopGetCurrent();

//获取当前的运行循环

CFRunLoopSourceRef sourceRef =

CFSoceketCreateRunLoopSource(KCFAllocatorDefault, _socket,0);

//创建一个运行循环源对象

CFRunLoopSource( cfrl , sourceRef, KCFRunLoopCommonModes);

//以该对象运行到当前运行循环中

CFRelease(sourceRef);

服务端响应

CFSocketCallBack callout, // 触发时调用的函数

该函数会在接收到客户端请求连接时触发:

ServerAcceptCallBack( //名字可以任意取,但参数是固定的

CFSoceketRef socket ,

CFSocketCallBackType callbacktype,

CFDataRef address,

const void * data, //与回调函数有关的特殊数据指针,

对于接受连接请求事件,这个指针指向该socket的句柄,

对于连接事件,则指向Sint32类型的错误代码

void *info) //与套接字关联的自定义的任意数据

{ //实现函数

If(kCFSocketAcceptCallBack = = type ){

CFSocketNativeHandle nativeSocketHandle = (CFSocketNativeHandle*)data;

//////////////////////以下片段用于输出来访者地址

Uint8_t name[SOCK_MAXADDRLEN]

Socklen_t namelen = sizeof(name);

If(0 != getpeername(nativeSocketHandle ,(struct sockaddr_in*)name,&namelen)) //获取地址

{

exit(1)

}

Printf(“%s connected\n”,inet_ntoa((struct sockaddr_in *)name)->sin_addr);

//////////////////////

CFReadStreamRef iStream;

CFWriteStreamRef oStream;

CFStreamCreatePairWithSocket( // 创建一个可读写的socket连接

kCFAllocatorDefault,

nativeSocketHandle,

&iStream,

&oStream);

If(iStream && oStream){

CFStreamClinetContext streamCtxt = {0,NULL, NULL, NULL, NULL};

If(!CFReadStreamSetClient(

iStream,

kCFStreamEventHasBytesAvailable //有可用数据则执行

readStream, //设置读取时候的函数

&steamCtxt))

{exit(1);}

If(!CFWriteStreamSetClient( //为流指定一个在运行循环中接受回调的客户端

oStream,

kCFStreamEventCanAcceptBytes, //输出流准备完毕,可输出

writeStream, //设置写入时候的函数

&steamCtxt))

{exit(1);}

}

}

}

读取流操作(触发式,被动技能)

readStream(CFReadStreamRef stream,CFStreamEventType eventType, void *client CallBackInfo)

{

UInt8 buff[255];

CFReadStreamRead(stream,buff,255); //将输入流中数据存入buff

Printf(“received %s”,buff);

}

CFWriteStreamRef outputStream = NULL; //输出流

写入流操作(仍然被动技能,在输出流准备好的时候调用)

writeStream (CFWriteStreamRef stream, CFStreamEventType eventType, void *clientCallBackInfo)

{

outputStream = stream; //输出流被指定

}

//主动输出,在输出流准备好之后才能调用

FucForWrite()

{

UInt8 buff[] = “Hunter21,this is Overlord”;

If(outputStream != NULL)

{

CFWriteStreamWrite(outputStream,buff,strlen(buff)+1);

}

}

------------------------------------------------------------------------------------------

ios编程笔记:CFSocket(客户端)

CFSocketRef _socket;

-(void)Connect

{

//////////////////////创建套接字//////////////

CFSocketContext CTX = {0,NULL,NULL,NULL,NULL};

_socket = CFSocketCreate(

kCFAllocatorDefault,

PF_INET,

SOCK_STREAM,

IPPROTO_TCP,

kCFSocketConnectCallBack, // 类型,表示连接时调用

ServerConnectCallBack, // 调用的函数

)

////////////////////////////设置地址///////////////////

NSString *serverAddr = @"192.168.0.110";

struct sockaddr_in addr

memset(&addr , 0,sizeof(addr));

addr.sin_len = sizeof(addr);

addr.sin_family = AF_INET;

addr.sin_port = htons(12345);

addr.sin_addr.s_addr = inet_addr([serverAddr UTF8String]);

CFDataRef address = CFDataCreate(

kCFAllocatorDefault,

(UInt8*)&addr,

sizeof(addr));

/////////////////////////////执行连接/////////////////////

CFSocketConnectToAddress(_socket,address,-1);

CFRunLoopRef cfrl = CFRunLoopGetCurrent(); // 获取当前运行循环

CFRunLoopSourceRef source = CFSocketCreateRunLoopSource(kCFAllocatorDefault,_socket,0);//定义循环对象

CFRunLoopAddSource(cfrl,source,kCFRunLoopCommonModes); //将循环对象加入当前循环中

CFRelease(source);

}

static void ServerConnectCallBack(

CFSocketRef socket,

CFSocketCallBackType type,

CFDataRef address,

const void *data,

void * info)

{

if(data != NULL)

{

printf("connect").//服务器那边已经提过,连接事件时该指针用于存放报错

}

else

{

printf("connect success");

}

}

///////////////////监听来自服务器的信息///////////////////

-(void)ReadStream

{

char buffer[255];

while(recv( CFSocektGetNative(_socket),buffer,sizeof(buffer),0))

{

printf(buffer);

}

}

/////////////////////////发送信息给服务器////////////////////////

- (void) sendMessage

{

NSString *stringToSend = @"Overlord,this is Hunter21";

const char *data = [stringToSend UTF8String];

send(CFSocketGetNative(_socket), data, strlen(data) + 1, 0);

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: