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);
}
2.FCSocket 接口比BSD socket多的多
服务器端和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等等,实际开发中需要实现的的东西。
如果没时间重复造轮子,用这类第三方框架也不错