在Swift开发过程中,确实能感觉到它的高效。不过虽然效率高但是有些功能还是借助C/C++来完成。所以学会Swift和C/C++交互还是必要的。下面以socket通讯库简单封装。
下面是客户端的c源码,阻塞之后连接好像有点问题,可能是我服务端没有处理这种机制。所以先不用阻塞的。
然后就是Swift中封装接口和使用源码
输出的结果:
下面是客户端的c源码,阻塞之后连接好像有点问题,可能是我服务端没有处理这种机制。所以先不用阻塞的。
// // socket.c // // Created by leehom on 16/2/16. // Copyright © 2016年 lee.demo. All rights reserved. // #include#include #include #include #include #include #include #include #include #include #include #include #include #include void _set_block(int socket,int on) { int flags; flags = fcntl(socket,F_GETFL,0); if (on==0) { fcntl(socket, F_SETFL, flags | O_NONBLOCK); }else{ flags &= ~ O_NONBLOCK; fcntl(socket, F_SETFL, flags); } } int _connect(const char *host,int port,int timeout){ struct sockaddr_in sa; struct hostent *hp; int sockfd = -1; hp = gethostbyname(host); if(hp==NULL){ return -1; } bcopy((char *)hp->h_addr, (char *)&sa.sin_addr, hp->h_length); sa.sin_family = hp->h_addrtype; sa.sin_port = htons(port); sockfd = socket(hp->h_addrtype, SOCK_STREAM, 0); _set_block(sockfd,1); int ret = connect(sockfd, (struct sockaddr *)&sa, sizeof(struct sockaddr)); if(ret == -1){ perror("连接失败\n"); exit(1); } fd_set fdwrite; struct timeval tvSelect; FD_ZERO(&fdwrite); FD_SET(sockfd, &fdwrite); tvSelect.tv_sec = timeout; tvSelect.tv_usec = 0; int retval = select(sockfd + 1,NULL, &fdwrite, NULL, &tvSelect); if (retval<0) { return -2; }else if(retval==0){//timeout return -3; }else{ int error=0; int errlen=sizeof(error); getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, (socklen_t *)&errlen); if(error!=0){ return -4;//connect fail } _set_block(sockfd, 1); int set = 1; setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&set, sizeof(int)); return sockfd; } } int _close(int socketfd){ return close(socketfd); } int _read(int socketfd,char *data,int len){ int readlen=(int)read(socketfd,data,len); return readlen; } int _write(int socketfd,const char *data,int len){ int byteswrite=0; while (len-byteswrite>0) { int writelen=(int)write(socketfd, data+byteswrite, len-byteswrite); if (writelen<0) { return -1; } byteswrite+=writelen; } return byteswrite; } //return socket fd int _listen(const char *addr,int port){ //create socket int socketfd=socket(AF_INET, SOCK_STREAM, 0); int reuseon = 1; setsockopt( socketfd, SOL_SOCKET, SO_REUSEADDR, &reuseon, sizeof(reuseon) ); //bind struct sockaddr_in serv_addr; memset( &serv_addr, ' ', sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = inet_addr(addr); serv_addr.sin_port = htons(port); int r=bind(socketfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)); if(r==0){ if (listen(socketfd, 128)==0) { return socketfd; }else{ return -2;//listen error } }else{ return -1;//bind error } } //return client socket fd int _accept(int onsocketfd,char *remoteip,int* remoteport){ socklen_t clilen; struct sockaddr_in cli_addr; clilen = sizeof(cli_addr); int newsockfd = accept(onsocketfd, (struct sockaddr *) &cli_addr, &clilen); char *clientip=inet_ntoa(cli_addr.sin_addr); memcpy(remoteip, clientip, strlen(clientip)); *remoteport=cli_addr.sin_port; if(newsockfd>0){ return newsockfd; }else{ return -1; } }
然后就是Swift中封装接口和使用源码
// // main.swift // // Created by leehom on 16/2/16. // Copyright © 2016年 lee.demo. All rights reserved. // import Foundation @asmname("_set_block") func setBlock(socket:CInt,on:CInt) @asmname("_connect") func connect(host:UnsafePointer,port:CInt,timeout:CInt)->CInt @asmname("_close") func close(socketfd:CInt)->CInt @asmname("_read") func read(socketfd:CInt,data:UnsafePointer ,len:CInt)->CInt @asmname("_write") func write(socketfd:CInt,data:UnsafePointer ,len:CInt)->CInt @asmname("_listen") func listener(addr:UnsafePointer ,port:CInt)->CInt @asmname("_accept") func accept(socketfd:CInt,remoteip:UnsafePointer ,remoteport:UnsafePointer )->CInt let fd = connect("127.0.0.1", port: 3333, timeout: 15000) if(fd != 0){ //setBlock(fd, on: 0)//设置非阻塞 let bufLen:Int = 1024000 var buf:[UInt8] = [UInt8](count:bufLen,repeatedValue:0x0) NSLog("开始读取数据...") let actual:CInt = read(fd,data:&buf,len:CInt(bufLen)) if(actual > 0){ NSLog("实际读取字节:%i", actual) let nString:String = NSString(bytes: buf, length: Int(actual), encoding: NSUTF8StringEncoding) as! String print(nString) }else{ NSLog("数据读取失败:%i", actual) } close(fd) }
输出的结果:
收藏的用户(0) X
正在加载信息~
推荐阅读
最新回复 (0)
站点信息
- 文章2302
- 用户1336
- 访客11053564
每日一句
Youth means limitless possibilities.
年轻就有无限的可能。
年轻就有无限的可能。
新会员