一、创建服务端,监听(阻塞模式)
定义个结构体,然后下面给赋值
#import
#import
@interface FirstBinding :NSObject
{
intsock_fd, client_fd;
struct sockaddr_in my_addr;
}
staticUInt16Port_num =16868;//socket服务端端口号
@implementation 实现
- (void)startService {
memset(&my_addr,0,sizeof(my_addr));//作用是在一段内存块中填充某个给定的值,它是对较大的结构体或数组进行清零操作的一种最快方法。
bzero(&my_addr,sizeof(my_addr));
my_addr.sin_family=AF_INET;
my_addr.sin_port=htons(Port_num);
my_addr.sin_addr.s_addr=htonl(INADDR_ANY);
my_addr.sin_len=sizeof(my_addr);
bzero(&(my_addr.sin_zero),8);
if((sock_fd=socket(AF_INET,SOCK_STREAM,0))== -1) {
NSLog(@"socket create error");
}else{
NSLog(@"socket create success");
}
//重用本地地址和端口
//这样的好处是,即使socket断了,调用前面的socket函数也不会占用另一个,而是始终就是一个端口
//这样防止socket始终连接不上,那么按照原来的做法,会不断地换端口。
intnREUSEADDR =1;
setsockopt(sock_fd,SOL_SOCKET,SO_REUSEADDR, (constchar*)&nREUSEADDR,sizeof(int));
//绑定这个接口
int bin =bind(sock_fd, (structsockaddr*)&my_addr,sizeof(structsockaddr));
if(bin == -1) {
NSLog(@"bind error");
if(Port_num<16868+10) {//如果开启失败,就循环指定的次数,给个限定,防止无线循环
Port_num++;
[selfstartService];
}
}else{
NSLog(@"bind success %d",Port_num);
}
if(listen(sock_fd,CONNECTNUMBER)==-1) {//开始监听
NSLog(@"listen error");
}else{
NSLog(@"listen success");
}
while(true) {//下面是阻塞的,不用担心无限循环下去
socklen_tsin_size=sizeof(structsockaddr_in);
if((client_fd=accept(sock_fd, (structsockaddr*)&remote_addr, &sin_size))==-1) {//开启成功后会一直监听客户端的连接
NSLog(@" accept error");
close(sock_fd);
if(client_fd== -1) {
NSLog(@"break");
break;
}
}else{
[self helloword];//有客户端连接进来,开始通讯
}
}
}