在iphone的平台下,要进行socket开发其实有很多种的方法,开源的库Asyncsocket,官方的CFSocket,还有BSD的socket。 
这里要做一个简单的socket普及,这里包含在socket的设置非阻塞喝超时的控制逻辑,心跳包和线程的启动时间同步的控制。 

这里都是标准的linux的流程 
先创建一个socket 

- (int)CSocket 
{ 
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) 
{ 
perror("socket"); 
exit(errno); 
} 
return sockfd; 
} 
然后是链接 
////////////////// 
- (BOOL)ConnectToServer:(NSString*)addr port:(int)port 
{ 
their_addr.sin_family = AF_INET; 
their_addr.sin_addr.s_addr = inet_addr([addr UTF8String]); 
their_addr.sin_port = htons(port); 
bzero(&(their_addr.sin_zero), 8); 
int conn = connect(sockfd, (struct sockaddr*)&their_addr, sizeof(struct sockaddr)); 
NSLog(@"Connect error no is %d:",conn); 
return misConnect; 
} 

这样子的链接是阻塞的,这样子就比较不好,可以设置成非阻塞的方式来控制超时 
/***************************************************/ 
//在connect之前,设成非阻塞模式 
int flags = fcntl(sockfd, F_GETFL,0); 
fcntl(sockfd,F_SETFL, flags | O_NONBLOCK); 
/*************************************************** 
//这是另外一种设置成非阻塞的方式 
int flags; 
if((flags = fcntl(sockfd, F_GETFL)) < 0 ) 
{ 
perror("fcntl F_SETFL"); 
} 
flags |= O_NONBLOCK; 
if(fcntl(sockfd, F_SETFL,flags) < 0) 
{ 
perror("fcntl"); 
} 
****************************************************/ 
设置connect后可以设置用select设置超时 
/***************************************************/ 
//设置超时 
fd_set fdwrite; 
struct timeval tvSelect; 

FD_ZERO(&fdwrite); 
FD_SET(sockfd, &fdwrite); 
tvSelect.tv_sec = 2; 
tvSelect.tv_usec = 0; 
int retval = select(sockfd + 1,NULL, &fdwrite, NULL, &tvSelect); 
if(retval < 0) 
{ 
if ( errno == EINTR ) 
{ 
NSLog(@"select error"); 
} 
else 
{ 
NSLog(@"error"); 
close(sockfd); 
} 
} 
else if(retval == 0) 
{ 
NSLog(@"select timeout........"); 
} 
else if(retval > 0) 
{ 
misConnect = YES; 
} 
/***************************************************/ 
//在connect成功之后,设成阻塞模式 
flags = fcntl(sockfd, F_GETFL,0); 
flags &= ~ O_NONBLOCK; 
fcntl(sockfd,F_SETFL, flags); 

/***************************************************/ 
//设置不被SIGPIPE信号中断,物理链路损坏时才不会导致程序直接被Terminate 
//在网络异常的时候如果程序收到SIGPIRE是会直接被退出的。 
struct sigaction sa; 
sa.sa_handler = SIG_IGN; 
sigaction( SIGPIPE, &sa, 0 ); 
/***************************************************/ 


然后就可以收发数据了 
send,write两种方法都可以,你需要自己维护一个队列,控制时间等等 
NSString *str = [SendCmdArray objectAtIndex:0]; 
NSData *data = [str dataUsingEncoding:NSISOLatin1StringEncoding]; 
// ssize_t datalen = send(sockfd,[data bytes],[data length],0); 
ssize_t datalen = write(sockfd, [data bytes], [data length]); 
if(datalen == [data length]) 
{ 
NSLog(@"Send str:%@",str); 
} 


如何接收数据,read和recv都可以,这是方法,你需要自己维护一个队列,控制时间等等。 
char readBuffer[512] = {0}; 
NSString* readString = nil; 
int br = 0; 
while (br = read(sockfd, readBuffer, sizeof(readBuffer)) < sizeof(readBuffer)) 
// while((br = recv(sockfd, readBuffer, sizeof(readBuffer), 0)) < sizeof(readBuffer)) 
{ 
NSLog(@"Received CMD:%s",readBuffer); 
readString = [NSString stringWithUTF8String:readBuffer]; 
memset(readBuffer,0,sizeof(readBuffer)); 
} 
NSLog(@"br is %d,receive exit.",br); 


获取时间后就可以进行时间同步了,具体的时间同步协议要根据自己平台来设计 
time_t timep; 
struct tm *p; 
time(&timep); 
p = localtime(&timep); 
int wday = -1;//return num is (0,6),the weekday range is (1,7) 
if(p->tm_wday == 0) 
wday = 7; 
else 
wday = p->tm_wday; 
char data[256] = {0}; 
sprintf(data,"0E4007%02x%02x%02x%02x%02x%02x%02x",(1900+p->tm_year)%100,(1+p->tm_mon),p->tm_mday,p->tm_hour,p->tm_min,p->tm_sec,wday); 
NSString *msgtime = [NSString stringWithUTF8String:data]; 

可以开一个线程来进行收发,处理相关的操作,想要多线程控制需要注意这个socket必须是全局可用的,因为新线程已经不在主循环了 
还有如果有界面更新也需要在主线程更新 

[NSThread detachNewThreadSelector:@selector(OnNewThread) toTarget:self withObject:nil]; 

可以用timer做一个心跳包维持通讯 

timer = [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(OnHeartBeatTimer:) userInfo:nil repeats:YES]; 

结束的时候记得关掉定时器和socket 
[timer invalidate]; 
close(sockfd);