MAC系统基于UNIX的核心系统增强了系统的稳定性、性能以及响应能力。由于unix需要付费,以及版本基本上不更新,很多采用unix系统的电脑转用linux,unix处于停滞不前状态,而linux由于是开源的,免费的,所以全球很多技术大牛在不断改进它,给它增加新技术,增加新理念,使它日新月异的发展。所以mac os后期主要借鉴linux的新技术,所以现在的mac os越来越像linux,linux也是来源于unix,他们师兄弟两个青出于蓝而胜于蓝。因此linux的socket的编程对苹果系统仍然有效。可以通过socket直接发送数据请求,可以通过fd创建多个连接,通过select对各个fd进行监控。要注意黏包的问题,可能网络不好或一段高频率的写数据不同的消息格式数据,开始可能没有立刻收到响应消息,有可能突然收到多个消息拼接在一起的字符串。有一种通而不达的情况,可能刚创建select后用select监听,服务器返回准备中,但是直到3.5分钟才能返回失败。
这个是我当时研究socket长连接的例子,由于非完整项目,没有解决粘包问题,由于只实现了部分功能,没有对消息格式进行严格定义和解析。只是实现了异步socket通信(收发消息)部分。不过我做的新项目这类的项目已经完美解决,由于公司信息案安全原因,不能泄露具体项目内容,但是它的原理是一样的,而且篇文章基本上没有加业务逻辑,所以更简单更容易看懂。
运行在mac的socket服务器demo下载地址:
http://download.csdn.net/download/jia12216/8929167
socket客户端app下载地址:http://download.csdn.net/download/jia12216/8929153
用java写的socket服务器测试桩下载地址:http://download.csdn.net/download/jia12216/8929101
运行在window电脑上socket服务器demo下载地址:http://download.csdn.net/download/jia12216/8929085
第三方库socket异步通信(robbiehanson/CocoaAsyncSocket)下载地址:https://github.com/robbiehanson/CocoaAsyncSocket/
注意:
inet_addr(“172.16.28.153”);这个要填你服务运行的电脑的ip,若有域名最好填域名(如:www.baidu.com).
.sin_port = htons(9123);这个你要连接的端口号,服务器和客户端的域名和端口好要一致。
客户端代码:
-(void)creatPushConnection
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, ), ^{
unsigned char recv_msg[BUFFER_SIZE+];
NSString *dec = nil;
NSInteger iStart = ;
unsigned char input_msg[];
int server_sock_fd;
int sd;
BOOL handleFlag = NO;
NSDate *curDate = nil;
unsigned char msg[+];
NSUInteger len = ;
//unsigned int m = 0;
long n = ;
unsigned char c;
long byte_num = ;
unsigned char *p = recv_msg;
char arr[BUFFER_SIZE+];
long m = , m1 = ;
NSString *message = nil;
NSString *str1=nil;
NSString *str2=nil;
unsigned int k = ;
NSError *error = nil;
Boolean bFlag = YES;
Boolean bstrEndFlag = NO;
NSData *da = nil;
g_LoginShiftState = SHIFT_STATE_INIT;
g_fd = -;
server_sock_fd = -;
SKIP:
//注意这段绑定ip和端口号的代码要放在这里防止出现网络类型变更,如:从wifi切换到4G,或4G切换到3G
struct sockaddr_in server_addr;
server_addr.sin_len = sizeof(struct sockaddr_in);
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons();
//server_addr.sin_addr.s_addr = inet_addr("172.16.28.106");
//server_addr.sin_addr.s_addr = inet_addr("172.16.28.25");
//server_addr.sin_addr.s_addr = inet_addr("172.16.28.157");
//server_addr.sin_addr.s_addr = inet_addr("0.0.0.0");
server_addr.sin_addr.s_addr = inet_addr("172.16.28.153");
bzero(&(server_addr.sin_zero),);
if(g_fd != -)
{
close(g_fd);
}
g_pushTime = ;
g_LoginShiftState = SHIFT_STATE_INIT;
g_fd = -;
server_sock_fd = -;
server_sock_fd = socket(AF_INET, SOCK_STREAM, );
sd = server_sock_fd;
if (server_sock_fd == -) {
NSLog(@"socket error");
return;
}
while()
{
g_fdWriteFlag = YES;
//将打开的socket设为非阻塞的,可以用fcntl(socket, F_SETFL, O_NDELAY)完成,网络不通75秒才返回结果
fcntl(socket, F_SETFL, O_NDELAY);
int i = connect(server_sock_fd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr_in));
NSLog(@"i= %d\n", i);
//发connect调用,这时返回-1,但是errno被设为EINPROGRESS,意即connect仍旧在进行还没有完成.
//getsockopt(socket, SOL_SOCKET, SO_ERROR, &error, sizeof(int));
来得到error的值,如果为零,则connect成功.
if ( i ==) {
g_fd = server_sock_fd;;
fd_set client_fd_set;
fd_set read_fd_set;
struct timeval tv;
tv.tv_sec = ;
tv.tv_usec = ;
//int max_fd = pipeFd;
int max_fd = server_sock_fd;
i = ;
while () {
g_fdWriteFlag = YES;
bzero(input_msg, );
FD_ZERO(&read_fd_set);
FD_SET(server_sock_fd, &read_fd_set);
struct timeval tv;
tv.tv_sec = ;
tv.tv_usec = ;
i = ;
if(max_fd < server_sock_fd)
{
max_fd = server_sock_fd;
}
int ret = select(max_fd + , &read_fd_set, NULL, NULL, &tv);
if (ret < ) {
NSLog(@"select 出错!\n");
goto SKIP;
}
else if(ret ==){
NSLog(@"select 超时!\n");
FD_ZERO(&client_fd_set);
FD_ZERO(&read_fd_set);
FD_SET(server_sock_fd, &client_fd_set);
FD_SET(server_sock_fd, &read_fd_set);
tv.tv_sec = ;
tv.tv_usec = ;
//socket一般都处于可写状态,除了网卡满了写不进去的罕见情况,所以该处侦听一般都是立刻响应
ret = select(max_fd + , &read_fd_set, &client_fd_set, NULL, &tv);
//[g_puTc lock];
if (ret < ) {
NSLog(@"select 出错!\n");
//[g_puTc unlock];
goto SKIP;
}
else if(ret ==){
NSLog(@"select 超时!\n");
//[g_puTc unlock];
continue;
}
else
{
//先把消息接收过来,后面再处理,防止再处理消息时,连接异常。
if (FD_ISSET(server_sock_fd, &read_fd_set))
{
NSLog(@"ret2= %d\n", ret);
bzero(recv_msg, BUFFER_SIZE);
long byte_num = recv(server_sock_fd,recv_msg,BUFFER_SIZE,);
if (byte_num > ) {
if (byte_num > BUFFER_SIZE) {
byte_num = BUFFER_SIZE;
}
recv_msg[byte_num] = '\0';
NSLog(@"服务器:%s\n",recv_msg);
handleFlag = YES;
}else if(byte_num < ){
NSLog(@"接收消息出错!\n");
//从实际运行上发现,若出现接收消息错误,后面无论如何接收消息都报同样的错误,所以还是关闭SOCKET,重新建立连接吧!
close(server_sock_fd);
goto SKIP;
}else{
//当socket可读,但是读到的字节数为0,说明是服务端退出
close(server_sock_fd);
NSLog(@"服务器端退出!\n");
goto SKIP;
}
}
//判断是否可写,若可写,并且有消息可以发送就像服务器推送消息。
if (FD_ISSET(server_sock_fd, &client_fd_set)) {
bzero(input_msg, BUFFER_SIZE);
if((g_LoginShiftState == SHIFT_STATE_INIT) || (g_LoginShiftState == SHIFT_STATE_UNLOGIN))
{
bzero(msg, );
snprintf(msg, sizeof(msg), "#################################################################POSITON latitude = %f, longitude = %f", g_latitude, g_longitude);
bzero(input_msg, );
snprintf(msg, sizeof(msg), "{\"head\":{\"token\":\"%s\",\"cmd\":\"0002\",\"result\":\"0\",\"ecode\":\"\",\"msg\":\"中国01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789e\"},\"body\":{}}", [g_token UTF8String]);
NSLog(@"msg= %s\n", msg);
len = strlen(msg);
snprintf(input_msg+, len+, "%s", msg);
NSUInteger m = ;
NSUInteger j = ;
m = len;
if(m/ == )
{
input_msg[j--] = m % ;
input_msg[j] = ;
}
else if(m/ == )
{
input_msg[j--] = m % ;
input_msg[j] = m/;
}
NSLog(@"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@input_msg1=%s\n", input_msg+);
ret = send(server_sock_fd, input_msg, len + , );
if (ret == -) {
NSLog(@"发送消息出错!\n");
NSLog(@"ret7= %d\n", ret);
}
else
{
if((g_LoginShiftState == SHIFT_STATE_INIT) || (g_LoginShiftState == SHIFT_STATE_UNLOGIN))
{
g_LoginShiftState = SHIFT_STATE_LOGINING;
}
NSLog(@"ret8= %d\n", ret);
}
}
else if(g_LoginShiftState == SHIFT_STATE_LOGINING)
{
curDate = [NSDate date];
NSTimeInterval nowTime = [curDate timeIntervalSince1970]*;
if(nowTime - g_pushTime >= *)
{
bzero(msg, );
snprintf(msg, sizeof(msg), "#################################################################POSITON latitude = %f, longitude = %f", g_latitude, g_longitude);
bzero(input_msg, BUFFER_SIZE);
snprintf(msg, sizeof(msg), "[{\"head\":{\"token\":\"%s\",\"cmd\":\"0001\",\"result\":\"0\",\"ecode\":\"\",\"msg\":\"中国\"},\"body\":{\"latitude\":%f,\"longitude\":%f}}]", [g_token UTF8String], g_latitude, g_longitude);
NSLog(@"msg= %s\n", msg);
len = strlen(msg);
snprintf(input_msg+, len+, "%s", msg);
NSUInteger m = ;
NSUInteger j = ;
m = len;
if(m/ == )
{
input_msg[j--] = m % ;
input_msg[j] = ;
}
else if(m/ == )
{
input_msg[j--] = m % ;
input_msg[j] = m/;
}
NSLog(@"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@input_msg2=%s\n", input_msg+);
while (!g_fdWriteFlag)
{
sleep();
}
g_fdWriteFlag = NO;
ret = send(server_sock_fd, input_msg, len + , );
if (ret == -) {
NSLog(@"发送消息出错!\n");
NSLog(@"ret7= %d\n", ret);
g_fdWriteFlag = YES;
//[g_puTc unlock];
goto SKIP;
}
else
{
NSLog(@"ret8= %d\n", ret);
g_pushTime = nowTime;
}
ret = send(server_sock_fd, input_msg, len + , );
if (ret == -) {
NSLog(@"发送消息出错!\n");
NSLog(@"ret7= %d\n", ret);
g_fdWriteFlag = YES;
//[g_puTc unlock];
goto SKIP;
}
else
{
NSLog(@"ret8= %d\n", ret);
g_pushTime = nowTime;
}
ret = send(server_sock_fd, input_msg, len + , );
if (ret == -) {
NSLog(@"发送消息出错!\n");
NSLog(@"ret7= %d\n", ret);
g_fdWriteFlag = YES;
//[g_puTc unlock];
goto SKIP;
}
else
{
NSLog(@"ret8= %d\n", ret);
g_pushTime = nowTime;
}
g_fdWriteFlag = YES;
}
}
}
//在此处处理服务器发过来的消息
//handleMessage
}
//[g_puTc unlock];
continue;
}
else
{
i = - tv.tv_sec;
NSLog(@"i= %d\n", i);
NSLog(@"&client_fd_set= %d\n", &client_fd_set);
if (FD_ISSET(server_sock_fd, &read_fd_set))
{
NSLog(@"ret2= %d\n", ret);
str1 = nil;
str2 = nil;
bFlag = YES;
bzero(recv_msg, BUFFER_SIZE+);
byte_num = recv(server_sock_fd,recv_msg,MESSAGE_HEADER_SIZE,);
if (byte_num == )
{
// if (byte_num > BUFFER_SIZE) {
// byte_num = BUFFER_SIZE;
// }
//recv_msg[byte_num] = '\0';
//NSLog(@"服务器:%s\n",recv_msg+2);
//dec = nil;
//iStart =h 0;
//bzero(arr, BUFFER_SIZE+1);
//memcpy(arr, recv_msg, BUFFER_SIZE);
c = recv_msg[];
//NSLog(@"服务器:%d\n",c);
n = c*;
//NSLog(@"服务器:%d\n",n);
c = recv_msg[];
//NSLog(@"服务器:%d\n",c);
n = n + c;
while ()
{
NSLog(@"服务器:消息队列解析。\n");
NSLog(@"服务器:%ld\n",n);
m1 = BUFFER_SIZE;
bstrEndFlag = NO;
if(n == )
{
NSLog(@"服务器:消息错误\n");
break;
}
else
{
bzero(recv_msg, BUFFER_SIZE+);
if(n <= BUFFER_SIZE)
{
//n = n;
byte_num = recv(server_sock_fd,recv_msg,n + ,);
NSLog(@"服务器:n = %d, byte_num = %d\n",n, byte_num);
if(byte_num == n)
{
str1 = [NSString stringWithCString:recv_msg encoding:NSUTF8StringEncoding];
NSLog(@"服务器:%@\n",str1);
break;
}
else if(byte_num == n + )
{
str1 = [NSString stringWithCString:recv_msg encoding:NSUTF8StringEncoding];
NSLog(@"服务器:%@\n",str1);
c = recv_msg[byte_num-];
//NSLog(@"服务器:%d\n",c);
n = c*;
//NSLog(@"服务器:%d\n",n);
c = recv_msg[byte_num-];
//NSLog(@"服务器:%d\n",c);
n = n + c;
break;
}
else
{
NSLog(@"服务器:消息格式错误\n");
break;
}
// str1 = nil;
// str2 = nil;
//
// bzero(recv_msg, BUFFER_SIZE+1);
// byte_num = recv(server_sock_fd,recv_msg,MESSAGE_HEADER_SIZE,0);
// if (byte_num != 2)
// {
// break;
// }
}
else
{
while (m1 > )
{
NSLog(@"服务器:消息字符串解析。\n");
bzero(recv_msg, BUFFER_SIZE+);
byte_num = recv(server_sock_fd,recv_msg,m1,);
if((byte_num != BUFFER_SIZE) && (!bstrEndFlag))
{
NSLog(@"服务器:消息格式错误\n");
bFlag = NO;
break;
}
else if((byte_num == m1) && (m1 == n + ) && (bstrEndFlag))
{
bFlag = YES;
c = recv_msg[m1-];
NSLog(@"服务器:c = %d\n",c);
n = c*;
c = recv_msg[m1-];
NSLog(@"服务器:c = %d\n",c);
n = n + c;
NSLog(@"服务器:n = %d\n",n);
recv_msg[m1-] ='\0';
recv_msg[m1-] = '\0';
}
else if((byte_num < n) && (bstrEndFlag))
{
NSLog(@"服务器:消息格式错误\n");
bFlag = NO;
break;
}
else if((byte_num == n) && (m1 == n + ) && (bstrEndFlag))
{
bFlag = NO;
}
NSLog(@"服务器:((byte_num == n) && (m1 == n + 2) && (bstrEndFlag)) = %d\n",((byte_num == n) && (m1 == n + ) && (bstrEndFlag)));
NSLog(@"服务器:byte_num = %d, n = %d, bFlag = %d, m1 = %d\n",byte_num, n, bFlag, m1);
if(str1 == nil)
{
str1 = [NSString stringWithCString:recv_msg encoding:NSUTF8StringEncoding];
}
else
{
str2 = [NSString stringWithCString:recv_msg encoding:NSUTF8StringEncoding];
str1 = [str1 stringByAppendingString:str2];
}
if(bstrEndFlag)
{
NSLog(@"服务器:%@\n",str1);
break;
}
//NSLog(@"服务器:m1 == BUFFER_SIZE = %d\n",m1 == BUFFER_SIZE);
n = n - BUFFER_SIZE;
if(n > BUFFER_SIZE)
{
m1 = BUFFER_SIZE;
}
else if((m1 == BUFFER_SIZE) && (n > ))
{
m1 = n + ;
bstrEndFlag = YES;
NSLog(@"服务器:m1 = %ld\n",m1);
}
else
{
break;
}
}
if(bFlag)
{
NSLog(@"服务器:%@\n",str1);
//在此处处理服务器发过来的消息
//handleMessage
str1 = nil;
str2 = nil;
}
else
{
break;
}
}
}
//while(1)
// {
// bzero(msg, BUFFER_SIZE);
// memcpy(msg, p+2, BUFFER_SIZE);
// //NSLog(@"服务器:%s\n",msg);
// bzero(arr, BUFFER_SIZE);
// //memcpy(arr, p+2, strlen(recv_msg+2));
// if(n < BUFFER_SIZE)
// {
// memcpy(arr, p+2, n);
// arr[BUFFER_SIZE] = '\0';
// NSLog(@"服务器:%s\n",arr)
// NSString *str=[NSString stringWithCString:arr encoding:NSUTF8StringEncoding];
// //NSLog(@"服务器:%d\n",[str length]);
// //NSLog(@"服务器:%@\n",str);
// NSError *error = nil;
//
// NSData *da= [str dataUsingEncoding:NSUTF8StringEncoding];
// NSLog(@"服务器:%d\n",[da length]);
//
//
// NSDictionary * dic = [NSJSONSerialization JSONObjectWithData:da options:NSJSONReadingMutableLeaves error:&error];
// if(dic != nil)
// {
// NSLog(@"服务器:%@\n",dic);
// NSLog(@"服务器:%d\n",[error code]);
//
// @try
// {
// NSDictionary * dicinfo = [dic objectForKey:@"head"];
// NSString * s1 = [dic objectForKey:@"body"];
// NSLog(@"服务器:%@\n",s1);
// NSLog(@"服务器:%@\n",dicinfo);
// //NSDictionary * dicinfo2 = [dic objectForKey:@"head1"];
// NSString * s2 = [dic objectForKey:@"bo1"];
// NSLog(@"服务器:%@\n",s2);
//
// }@catch (NSException * e) {
// NSLog(@@"Exception: %@", e);
//
// }
// }
// else
// {
// NSLog(@"服务器:消息格式错误");
// }
//
// }
// else
// {
//
// m = n;
// memcpy(arr, p+2, n);
// arr[BUFFER_SIZE] = '\0';
// NSLog(@"服务器:%s\n",arr)
// str1 = [NSString stringWithCString:arr encoding:NSUTF8StringEncoding];
// bzero(recv_msg, BUFFER_SIZE);
// byte_num = recv(server_sock_fd,recv_msg,BUFFER_SIZE,0);
// while (1)
// {
// p = recv_msg;
// memcpy(arr, p+2, n);
// arr[BUFFER_SIZE] = '\0';
// NSLog(@"服务器:%s\n",arr)
// str2 = [NSString stringWithCString:arr encoding:NSUTF8StringEncoding];
// message = [str1 stringByAppendingString:str2];
// str1 = message;
// if(n == [str1 length])
// {
//
// }
// }
//
// }
//
//
//
// break;
//
//
//
//
// }
}
//[self decodePushMessage:recv_msg:dec:&iStart];
}
else if(byte_num == )
{
NSLog(@"无法识别的消息!\n");
}
else if(byte_num < )
{
NSLog(@"接收消息出错!\n");
//从实际运行上发现,若出现接收消息错误,后面无论如何接收消息都报同样的错误,所以还是关闭SOCKET,重新建立连接吧!
close(server_sock_fd);
goto SKIP;
}
else{
close(server_sock_fd);
NSLog(@"服务器端退出!\n");
goto SKIP;
//exit(0);
}
}
FD_ZERO(&client_fd_set);
FD_ZERO(&read_fd_set);
FD_SET(server_sock_fd, &client_fd_set);
FD_SET(server_sock_fd, &read_fd_set);
tv.tv_sec = ;
tv.tv_usec = ;
//socket一般都处于可写状态,除了网卡满了写不进去的罕见情况,所以该处侦听一般都是立刻响应
ret = select(server_sock_fd + , &read_fd_set, &client_fd_set, NULL, &tv);
//[g_puTc lock];
if (ret < ) {
NSLog(@"select 出错!\n");
//[g_puTc unlock];
goto SKIP;
}
else if(ret ==){
NSLog(@"select 超时!\n");
//[g_puTc unlock];
continue;
}
else{
NSLog(@"ret4= %d\n", ((FD_ISSET(server_sock_fd, &client_fd_set)) && (FD_ISSET(server_sock_fd, &read_fd_set))));
i = - tv.tv_sec;
NSLog(@"i= %d\n", i);
//先把消息接收过来,后面再处理,防止在处理消息时,连接异常。
if (FD_ISSET(server_sock_fd, &read_fd_set))
{
NSLog(@"ret2= %d\n", ret);
bzero(recv_msg, BUFFER_SIZE);
long byte_num = recv(server_sock_fd,recv_msg,BUFFER_SIZE,);
if (byte_num > ) {
if (byte_num > BUFFER_SIZE) {
byte_num = BUFFER_SIZE;
}
recv_msg[byte_num] = '\0';
NSLog(@"服务器:%s\n",recv_msg);
handleFlag = YES;
}else if(byte_num < ){
NSLog(@"接受消息出错!\n");
}else{
close(server_sock_fd);
NSLog(@"服务器端退出!\n");
goto SKIP;
//exit(0);
}
}
//判断是否可写,若可写,并且有消息可以发送就像服务器推送消息。
if (FD_ISSET(server_sock_fd, &client_fd_set)) {
bzero(input_msg, BUFFER_SIZE);
if((g_LoginShiftState == SHIFT_STATE_INIT) || (g_LoginShiftState == SHIFT_STATE_UNLOGIN))
{
bzero(msg, BUFFER_SIZE);
snprintf(msg, sizeof(msg), "#################################################################POSITON latitude = %f, longitude = %f", g_latitude, g_longitude);
bzero(input_msg, BUFFER_SIZE);
snprintf(msg, sizeof(msg), "{\"head\":{\"token\":\"%s\",\"cmd\":\"0002\",\"result\":\"0\",\"ecode\":\"\",\"msg\":\"\"},\"body\":{}}", [g_token UTF8String]);
NSLog(@"msg= %s\n", msg);
len = strlen(msg);
snprintf(input_msg+, len+, "%s", msg);
NSUInteger m = ;
NSUInteger j = ;
m = len;
if(m/ == )
{
input_msg[j--] = m % ;
input_msg[j] = ;
}
else if(m/ == )
{
input_msg[j--] = m % ;
input_msg[j] = m/;
}
NSLog(@"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@input_msg3=%s\n", input_msg+);
while (!g_fdWriteFlag)
{
sleep();
}
g_fdWriteFlag = NO;
ret = send(server_sock_fd, input_msg, len + , );
if (ret == -) {
NSLog(@"发送消息出错!\n");
NSLog(@"ret7= %d\n", ret);
g_fdWriteFlag = YES;
//[g_puTc unlock];
goto SKIP;
}
else
{
if((g_LoginShiftState == SHIFT_STATE_INIT) || (g_LoginShiftState == SHIFT_STATE_UNLOGIN))
{
g_LoginShiftState = SHIFT_STATE_LOGINING;
}
NSLog(@"ret8= %d\n", ret);
}
g_fdWriteFlag = YES;
}
else if(g_LoginShiftState == SHIFT_STATE_LOGINING)
{
curDate = [NSDate date];
NSTimeInterval nowTime = [curDate timeIntervalSince1970]*;
if(nowTime - g_pushTime >= *)
{
bzero(msg, );
snprintf(msg, sizeof(msg), "#################################################################POSITON latitude = %f, longitude = %f", g_latitude, g_longitude);
bzero(input_msg, BUFFER_SIZE);
snprintf(msg, sizeof(msg), "{\"head\":{\"token\":\"%s\",\"cmd\":\"0001\",\"result\":\"0\",\"ecode\":\"\",\"msg\":\"\"},\"body\":{\"latitude\":%f,\"longitude\":%f}}", [g_token UTF8String], g_latitude, g_longitude);
NSLog(@"msg= %s\n", msg);
len = strlen(msg);
snprintf(input_msg+, len+, "%s", msg);
NSUInteger m = ;
NSUInteger j = ;
m = len;
if(m/ == )
{
input_msg[j--] = m % ;
input_msg[j] = ;
}
else if(m/ == )
{
input_msg[j--] = m % ;
input_msg[j] = m/;
}
NSLog(@"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@input_msg4=%s\n", input_msg+);
while (!g_fdWriteFlag)
{
sleep();
}
g_fdWriteFlag = NO;
ret = send(server_sock_fd, input_msg, len + , );
if (ret == -) {
NSLog(@"发送消息出错!\n");
NSLog(@"ret7= %d\n", ret);
g_fdWriteFlag = YES;
//[g_puTc unlock];
goto SKIP;
}
else
{
NSLog(@"ret8= %d\n", ret);
g_pushTime = nowTime;
}
g_fdWriteFlag = YES;
}
}
}
//在此处处理服务器发过来的消息
//handleMessage
//[g_puTc unlock];
}
}
}
}
else
{
close(server_sock_fd);
//flag = 1;
sleep();
goto SKIP;
}
}
});
}
服务端代码:
- (void)windowControllerDidLoadNib:(NSWindowController *)aController
{
[super windowControllerDidLoadNib:aController];
[_nsT setStringValue:@"set sth."];
struct sockaddr_in server_addr;
server_addr.sin_len = sizeof(struct sockaddr_in);
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons();
//server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
server_addr.sin_addr.s_addr = inet_addr("172.16.28.123");
bzero(&(server_addr.sin_zero),);
char recv_msg[];
char input_msg[BUFFER_SIZE];
//创建socket
int server_sock_fd = socket(AF_INET, SOCK_STREAM, );
if (server_sock_fd == -) {
perror("socket error");
return;
}
//绑定socket
int bind_result = bind(server_sock_fd, (struct sockaddr *)&server_addr, sizeof(server_addr));
if (bind_result == -) {
perror("bind error");
return;
}
//listen
if (listen(server_sock_fd, BACKLOG) == -) {
perror("listen error");
return;
}
int kq = kqueue();
if (kq == -) {
perror("创建kqueue出错!\n");
exit();
}
struct kevent event_change;
EV_SET(&event_change, STDIN_FILENO, EVFILT_READ, EV_ADD, , , NULL);
kevent(kq, &event_change, , NULL, , NULL);
EV_SET(&event_change, server_sock_fd, EVFILT_READ, EV_ADD, , , NULL);
kevent(kq, &event_change, , NULL, , NULL);
while () {
struct timespec timeout = {,};
int ret = kevent(kq, NULL, , events, , &timeout);
if (ret < ) {
printf("kevent 出错!\n");
continue;
}else if(ret == ){
printf("kenvent 超时!\n");
continue;
}else{
//ret > 0 返回事件放在events中
for (int i = ; i < ret; i++) {
struct kevent current_event = events[i];
//kevent中的ident就是文件描述符
if (current_event.ident == STDIN_FILENO) {
//标准输入
bzero(input_msg, BUFFER_SIZE);
fgets(input_msg, BUFFER_SIZE, stdin);
//输入 ".quit" 则退出服务器
if (strcmp(input_msg, QUIT_CMD) == ) {
exit();
}
for (int i=; i<CONCURRENT_MAX; i++) {
if (client_fds[i]!=) {
send(client_fds[i], input_msg, BUFFER_SIZE, );
}
}
}else if(current_event.ident == server_sock_fd){
//有新的连接请求
struct sockaddr_in client_address;
socklen_t address_len;
int client_socket_fd = accept(server_sock_fd, (struct sockaddr *)&client_address, &address_len);
if (client_socket_fd > ) {
int index = -;
for (int i = ; i < CONCURRENT_MAX; i++) {
if (client_fds[i] == ) {
index = i;
client_fds[i] = client_socket_fd;
break;
}
}
if (index >= ) {
EV_SET(&event_change, client_socket_fd, EVFILT_READ, EV_ADD, , , NULL);
kevent(kq, &event_change, , NULL, , NULL);
printf("新客户端(fd = %d)加入成功 %s:%d \n",client_socket_fd,inet_ntoa(client_address.sin_addr),ntohs(client_address.sin_port));
}else{
bzero(input_msg, BUFFER_SIZE);
strcpy(input_msg, "服务器加入的客户端数达到最大值,无法加入!\n");
send(client_socket_fd, input_msg, BUFFER_SIZE, );
printf("客户端连接数达到最大值,新客户端加入失败 %s:%d \n",inet_ntoa(client_address.sin_addr),ntohs(client_address.sin_port));
}
}
}else{
//处理某个客户端过来的消息
bzero(recv_msg, BUFFER_SIZE);
long byte_num = recv((int)current_event.ident,recv_msg,BUFFER_SIZE,);
if (byte_num > ) {
if (byte_num > BUFFER_SIZE) {
byte_num = BUFFER_SIZE;
}
recv_msg[byte_num] = '\0';
printf("客户端(fd = %d):%s\n",(int)current_event.ident,recv_msg);
//sleep(3);
bzero(input_msg, BUFFER_SIZE);
strcpy(input_msg, "123454678!\n");
if(send((int)current_event.ident, input_msg, BUFFER_SIZE, ) == -)
{
perror("send error");
}
else
{
printf("input_msg%s\n", input_msg);
}
//printf("input_msg %s:%d \n",inet_ntoa(((int)current_event.ident).sin_addr),ntohs(((int)current_event.ident).sin_port));
}else if(byte_num < ){
printf("从客户端(fd = %d)接受消息出错.\n",(int)current_event.ident);
}else{
EV_SET(&event_change, current_event.ident, EVFILT_READ, EV_DELETE, , , NULL);
kevent(kq, &event_change, , NULL, , NULL);
close((int)current_event.ident);
for (int i = ; i < CONCURRENT_MAX; i++) {
if (client_fds[i] == (int)current_event.ident) {
client_fds[i] = ;
break;
}
}
printf("客户端(fd = %d)退出了\n",(int)current_event.ident);
}
}
}
}
}
// Add any code here that needs to be executed once the windowController has loaded the document's window.
}