ios编程笔记:CFSocket

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(recvCFSocektGetNative(_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);
 }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值