socket编程---之多连接服务端实现(CFNetwork框架)
来源:互联网 发布:中小学课本同步软件 编辑:程序博客网 时间:2024/06/05 08:16
#include <stdio.h>#include <stdlib.h>#include <sys/types.h>#include <sys/socket.h>#include <sys/fcntl.h>#include <sys/select.h>#include <sys/time.h>#include <sys/ioctl.h>#include <netinet/in.h>#include <arpa/inet.h>#include <unistd.h>#include <string.h>#include <sys/errno.h>#import <CFNetwork/CFNetwork.h>#import <Foundation/Foundation.h>CFReadStreamRef readStream;CFWriteStreamRef writeStream;// --读取接收缓冲区的回调函数 当CFReadStreamRef有可读的数据或者发送其它事件时该函数由系统自动调用static void readStreamCallBack(CFReadStreamRef stream, CFStreamEventType eventType, void *clientCallBackInfo) { switch (eventType) { case kCFStreamEventHasBytesAvailable: { UInt8 buff[255]; if(CFReadStreamRead(stream, buff, 255) > 0 ){ NSLog(@"接收到的数据为:%s",buff); UInt8 sendbuff[255] = "hello!"; CFIndex bytesToSend = CFWriteStreamWrite(writeStream, sendbuff, sizeof(buff)); if(bytesToSend > 0){ NSLog(@"像客户端发送数据成功..."); }else if (bytesToSend == 0){ NSLog(@"writeStream 已满,无法写入数据...."); }else{ NSLog(@"发送出错"); } }else{ NSLog(@"没有数据了...."); } } default: { if (eventType == kCFStreamEventEndEncountered) { NSLog(@"接收缓存区中没有数据了...."); }else if (eventType == kCFStreamEventErrorOccurred){ NSLog(@"出错了...."); } } break; }}// --向客户端写数据的回调函数 仅当调用CFWriteStreamWrite()函数时该函数才被调用.static void writeStreamCallBack(CFWriteStreamRef stream, CFStreamEventType eventType, void *clientCallBackInfo) { switch (eventType) { case kCFStreamEventCanAcceptBytes:{ break; } default: break; } }// --等待客户端连接的回调函数static void serverSocketCallBack(CFSocketRef s, CFSocketCallBackType type, CFDataRef address, const void *data, void *info){ if ( type != kCFSocketAcceptCallBack ) { return; } CFSocketNativeHandle nativeSocketHandle = *(CFSocketNativeHandle*)data; // --客户端连接的socket信息 struct sockaddr_in client_add; socklen_t clientLen = sizeof(client_add); if (getpeername(nativeSocketHandle, (struct sockaddr *)&client_add, &clientLen) == -1) { perror("getpeername()"); exit(0); } NSString *ip = [[NSString alloc] initWithCString:inet_ntoa(client_add.sin_addr) encoding:NSASCIIStringEncoding]; NSString *port = [NSString stringWithFormat:@"%d",client_add.sin_port]; NSLog(@"连接的客户端为:%@%@",ip,port); // --4.创建和客户端socket的读写缓存 CFStreamCreatePairWithSocket(kCFAllocatorDefault, nativeSocketHandle, &readStream, &writeStream); if (readStream && writeStream) { CFStreamClientContext streamContext = {0,NULL, NULL, NULL}; // --一个标记CFStreamRead/Write的上下文 if (!CFReadStreamSetClient(readStream, kCFStreamEventHasBytesAvailable,readStreamCallBack,&streamContext)){ // --设置接收缓存区的回调函数 exit(1); } if (!CFWriteStreamSetClient(writeStream, kCFStreamEventCanAcceptBytes, writeStreamCallBack, &streamContext)){ // --设置发送缓冲区的回调函数 exit(1); } CFReadStreamScheduleWithRunLoop(readStream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); // --将readStream加入runloop,这样才可以不停的读取数据 CFWriteStreamScheduleWithRunLoop(writeStream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); // --将writeStream加入runloop,这样才可以不停的发送数据 CFReadStreamOpen(readStream); // --打开readStream才会工作 CFWriteStreamOpen(writeStream); // --打开writeStream才会工作 } else { close(nativeSocketHandle); }}int main(int argc, const char * argv[]) { @autoreleasepool { // --1.创建服务器端socket CFSocketContext socketContext = {0,NULL,NULL,NULL}; CFSocketRef serverSocket = CFSocketCreate(kCFAllocatorDefault, AF_INET, SOCK_STREAM, IPPROTO_TCP, kCFSocketAcceptCallBack, serverSocketCallBack, &socketContext); if (serverSocket == NULL) { perror("create socket"); exit(0); } // --2.绑定并监听某个地址 struct sockaddr_in socketAddress; memset(&socketAddress, 0, sizeof(socketAddress)); socketAddress.sin_len = sizeof(socketAddress); socketAddress.sin_family = AF_INET; socketAddress.sin_port = htons(2125); socketAddress.sin_addr.s_addr = htonl(INADDR_ANY); NSData *addressData = [NSData dataWithBytes:&socketAddress length:sizeof(socketAddress)]; if (CFSocketSetAddress(serverSocket, (__bridge CFDataRef)addressData) != kCFSocketSuccess) { perror("bind && listen"); if (serverSocket != NULL) { CFRelease(serverSocket); serverSocket = NULL; } } // --3.添加到runloop中,等待连接请求,这里默认的实现是可以接收多个客户端的连接 CFRunLoopRef currentRunloop = CFRunLoopGetCurrent(); if (serverSocket == NULL) { exit(0); } CFRunLoopSourceRef runloopSourse = CFSocketCreateRunLoopSource(NULL, serverSocket, 0); CFRunLoopAddSource(currentRunloop, runloopSourse, kCFRunLoopDefaultMode); CFRunLoopRun(); } return 0;}
0 0
- socket编程---之多连接服务端实现(CFNetwork框架)
- socket编程---之多连接服务端实现(select函数方式)
- socket编程---之多连接服务端实现(多线程方式)
- Socket编程简单实现服务端客户端连接
- socket编程---之单连接服务端实现
- Java Socket编程之多线程实现C/S一对多(服务端无法发送数据)
- JAVA SOCKET网络编程,服务端接收多个客户端连接的实现
- 网络编程--基于java socket通信,实现多个客户端连接同一服务端
- CFNetwork框架
- Socket多连接服务端
- socket的服务端框架
- socket的服务端框架
- socket通信服务端编程
- Android与服务端的Socket连接实现简单数据传输
- Android客户端 C#服务端 实现socket长连接
- Java Socket实现多个客户端连接同一个服务端
- C++ socket编程 实现服务端与客户端的通讯
- 【黑马程序员】Socket编程实现服务端和客户端的交互
- DBN和DNN的区别(未完待续)
- 素性测试poj1811
- 网站建设与制作基本的流程
- 网站建设规划书
- oracle 11g授权创建用户
- socket编程---之多连接服务端实现(CFNetwork框架)
- python 版DES和MAC算法
- Android音乐播放——MediaPlayer, unable to create media player
- John the Ripper使用方法概述
- 第二次
- 如何学习一项新技术,以redis为例
- Java程序员的JavaScript学习笔记(4——闭包/getter/setter)
- gps纠偏接口返回示例
- 第二章 知识导图