1.基于 C 的 BSD socket(UNIX系统中通用的网络接口)
感觉BSD socket 最容易理解,最容易入门,最为灵活 但是最难用,尤其对于大型项目
需要导入头文件
#import <sys/socket.h> #import <netdb.h>
int listenfd, connfd; struct sockaddr_in servaddr; char buff[4096]; long n; int i=100; //创建 socket if( (listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1 ){ printf("create socket error: %s(errno: %d)\n",strerror(errno),errno); return; } //初始化ip地址 memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(8088);//要与客户端请求的端口网址一样 //绑定 网址端口 if( bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) == -1){ printf("bind socket error: %s(errno: %d)\n",strerror(errno),errno); return; } //监听 网址端口 if( listen(listenfd, 10) == -1){ printf("listen socket error: %s(errno: %d)\n",strerror(errno),errno); return; } //接受服务器传来的数据 printf("======waiting for client's request======\n"); while(i>0){ if( (connfd = accept(listenfd, (struct sockaddr*)NULL, NULL)) == -1){ printf("accept socket error: %s(errno: %d)",strerror(errno),errno); continue; } n = recv(connfd, buff, MAXLINE, 0); buff[n] = '\0'; printf("recv msg from client: %s\n", buff); close(connfd); } //关闭socket close(listenfd);
-(void)sendDataToServerURL:(NSURL *)url{ int sockfd; char sendline[4096]; struct sockaddr_in servaddr; NSString * host = [url host]; //创建 socket if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){ printf("create socket error: %s(errno: %d)\n", strerror(errno),errno); return; } //初始化ip地址 struct hostent * hostEnt = gethostbyname([host UTF8String]);//根据域名 获取ip信息 if (NULL == hostEnt) { NSLog(@"解析域名失败"); return; } struct in_addr * remoteInAddr = (struct in_addr *)hostEnt->h_addr_list[0]; memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(8088); servaddr.sin_addr = *remoteInAddr; //链接TCP服务器(根据ip地址) if(connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0){ printf("connect error: %s(errno: %d)\n",strerror(errno),errno); return; } //发送字符串到TCP服务器 printf("send msg to server: \n"); fgets(sendline, 4096, stdin); if(send(sockfd, sendline, strlen(sendline), 0) < 0) { printf("send msg error: %s(errno: %d)\n", strerror(errno), errno); return; } //关闭socket close(sockfd); }
服务器端和BSD socket有点类似,
客户端的与BSD socket完全不同,使用的是输入输出流。
服务器端
//收到消息监听 static void handleConnect(CFSocketRef sock, CFSocketCallBackType type, CFDataRef address, const void *data, void *info) { NSLog(@"收到信息了"); } -(void)openFCSocket { //创建 socket const CFSocketContext socketCtxt = {0, (__bridge void *)self, NULL, NULL, NULL}; CFSocketRef cfSocket = CFSocketCreate( kCFAllocatorDefault, PF_INET, SOCK_STREAM, IPPROTO_TCP, kCFSocketAcceptCallBack, (CFSocketCallBack)handleConnect,//接受信息回调 &socketCtxt); if (cfSocket == NULL) { NSLog(@"创建Socket失败"); return; } //初始化ip地址 struct sockaddr_in sin; memset(&sin, 0, sizeof(sin)); sin.sin_len = sizeof(sin); sin.sin_family = AF_INET; /* Address family */ sin.sin_port = htons(8088); /* Or a specific port */ sin.sin_addr.s_addr= INADDR_ANY; //绑定 网址端口 CFDataRef sincfd = CFDataCreate( kCFAllocatorDefault, (UInt8 *)&sin, sizeof(sin)); if (kCFSocketSuccess != CFSocketSetAddress(cfSocket, sincfd)) { NSLog(@"绑定网址端口失败"); } CFRelease(sincfd); //将socket加入 run loop CFRunLoopSourceRef socketsource = CFSocketCreateRunLoopSource( kCFAllocatorDefault, cfSocket, 0); CFRunLoopAddSource( CFRunLoopGetCurrent(), socketsource, kCFRunLoopDefaultMode); }
NSString *host = @"127.0.0.1"; int port = 8088; //创建输入 输出流 CFReadStreamRef readStream; CFWriteStreamRef writeStream; CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, (__bridge CFStringRef)host, port, &readStream, &writeStream); NSInputStream *inputStream = (__bridge NSInputStream *)readStream; NSOutputStream *outputStream = (__bridge NSOutputStream *)writeStream; if (inputStream == nil || outputStream == nil) { NSLog(@"流创建失败!"); return ; } //启动输入 输出流 [inputStream open]; [outputStream open]; //发送数据 NSData *outgoingDataBuffer = [@"testdata" dataUsingEncoding:NSUTF8StringEncoding]; NSInteger writtenBytes = [outputStream write:outgoingDataBuffer.bytes maxLength:outgoingDataBuffer.length]; if ( writtenBytes == -1 ) { NSLog(@"发送失败"); return; } NSLog(@"发送成功");
3. CocoaAsyncSocket封装了CFSocket
实现了TCP,UDP,加入异步线程,断开重连,TLS/SSL等等,实际开发中需要实现的的东西。
如果没时间重复造轮子,用这类第三方框架也不错