Socket超时时会崩溃!try catch语句也不能捕获!
-(void)inte易做图ceForsock:(NSString *)filename Path:(NSString *)path{int sock = 0;
sock = [self sockInit:sock];
[self upData:sock filename:[filename UTF8String] Path:[path UTF8String]];
close(sock);
NSLog(@"socke上传成功");
}
-(int)upData:(int)sock filename:(const char *)filename Path:(const char *)path{
int local;
int fd;
int ret;
int readSize;
int timeOutVal = 0;
int len = 0;
char headSize[10];
char recvInfo[35];
char sendFilename[50];
char dir[256];
char buf[8196];
#ifdef DebugLog
NSLog(@"filename is : %s",filename);
NSLog(@"dir is : %s",path);
#endif
fd_set wfds;
struct timeval tv;
FD_ZERO(&wfds);
FD_SET(sock, &wfds);
tv.tv_sec = 200;
tv.tv_usec = 0;
memset(dir, 0, 256);
memset(sendFilename, 0, 50);
memset(recvInfo, 0, 35);
strcat(sendFilename, filename);
strcat(dir, path);
sendFilename[strlen(sendFilename)] = '*';
send(sock, "0000000064", 10, 0);
send(sock, "4000", 4, 0);
send(sock, sendFilename, 50, 0);
recv(sock, recvInfo, 34, 0);
local = atoi(recvInfo+14);
if(strncmp(recvInfo+10, "4001", 4) == 0){
fd = open(dir, O_RDONLY);
if(fd < 0){
printf("open failed in %s and %d\n",__FUNCTION__,__LINE__);
return 0;
}
lseek(fd, local, SEEK_SET);
// printf("%d\n",local);
while (1) {
ret = select(sock+1, NULL, &wfds, NULL, &tv);
if(ret < 0){
printf("select failed in %s and %d\n",__FUNCTION__,__LINE__);
close(fd);
return 0;
}else if(ret == 0){
if(timeOutVal == 5){
timeOutVal = 0;
close(fd);
return 0;
}
timeOutVal++;
continue;
}
if(FD_ISSET(sock, &wfds)){
memset(buf, 0, 8196);
readSize = read(fd, buf, 8196);
if((readSize <= 0)){
memset(headSize, '0', 10);
iTos(headSize, readSize);
send(sock, "0000000034", 10, 0);
send(sock, "4003", 4, 0);
send(sock, headSize, 20, 0);
//len += readSize;
#ifdef DebugLog
printf("%s\n",headSize);
printf("readSize : %d\n",readSize);
printf("len : %d\n",len);
#endif
recv(sock, recvInfo, 34, 0);
if(strncmp(recvInfo+10, "4004", 4) == 0){
close(fd);
return 0;
}else if(strncmp(recvInfo+10, "4002", 4) == 0){
continue;
}
}
/*
if(readSize <= 0){
close(fd);
return 0;
}
*/
memset(headSize, '0', 10);
iTos(headSize, readSize+10+4);
// printf("handSize : %s\n",headSize);
send(sock, headSize, 10, 0);
send(sock, "4002", 4, 0);
send(sock, buf, readSize, 0);
len += readSize;
// printf("readSize : %d\n",readSize);
recv(sock, recvInfo, 34, 0);
if(strncmp(recvInfo+10, "4004", 4) == 0){
close(fd);
return 0;
}else if(strncmp(recvInfo+10, "4002", 4) == 0){
continue;
}
}
}
}
return 0;
}
纯C写的 ,Socket超时时会崩溃!try catch语句也不能捕获!请问有什么方法解决呢?请大牛出来帮忙! --------------------编程问答-------------------- 是不是收到一个SIG_PIPE的信号,,使用signal函数捕获这个信号, --------------------编程问答-------------------- send和recv的时候都判断一下是否成功,既然超时了,就未必会成功,后续的一些字符串操作应该会引起异常。
调试时看不到异常的断点? --------------------编程问答-------------------- http://blog.sina.com.cn/s/blog_7011f21c0101coh2.html
在使用socket的send函数时,如果此时服务器断开连接,socket将会收到broken pipe的错误。我们可以判断类似的错误来进行重连,但是在这之前系统就会发出SIGPIPE的信号,导致我们的程序crash。所以我们需要先屏蔽sigpipe的信号
struct sigaction sa;
struct sigaction osa;
sa.sa_handler = custom_handle;
sigaction(SIGPIPE, &sa, &osa);
这样我们在收到系统的SIGPIPE信号后就不会crash,而是会跑到我们自定义的handle函数里面
当然我们还不能忘记在socket不使用的时候还原系统的信号设置
sigaction(SIGPIPE, &osa, 0);
这时我们的程序虽然不会crash,但是在debug会非常恼人的收到系统触发的debug中断,使得我们的调试非常烦躁,我个人的解决方法是调试时候在入口设置断点,是debug console进入 gdb或是lldb的状态 然后忽略SIGPIPE信号的stop
gdb
handle SIGPIPE nostop
lldb
process handle SIGPIPE -s false
--------------------编程问答-------------------- 我之前碰到过一次网络超时闪退,后来查看信号是sig 9,并不是崩溃,是进程被系统kill掉了。
补充:移动开发 , iPhone