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

你可能感兴趣的:(ios编程笔记:CFSocket)