linux - asynchronous socket server, killing thread c -
im having kind of trouble on asynchronous socket server in c, though in moving java, first want solve problem.
i have detached thread each connection (not client), when done closes it, im having problem when server gets 2 connections @ same time, kind of leave old behind , starts new...
this code:
int main( int argc, char *argv[] ) { int server_portno=1111; int sockfd, newsockfd,option=1; int *new_sock; socklen_t clilen; struct sockaddr_in serv_addr, cli_addr; /* first call socket() function */ sockfd = socket(af_inet, sock_stream, 0); if (sockfd < 0) { addlog("error opening socket\n"); exit(1); } /* initialize socket structure */ bzero((char *) &serv_addr, sizeof(serv_addr)); serv_addr.sin_family = af_inet; serv_addr.sin_addr.s_addr = inaddr_any; serv_addr.sin_port = htons(server_portno); /* bind host address using bind() call.*/ if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { addlog("error on binding\n"); exit(1); } if(setsockopt(sockfd,sol_socket,so_reuseaddr,&option,sizeof(option)) < 0) { addlog("setsockopt failed\n"); close(sockfd); exit(2); } /* start listening clients, here * process go in sleep mode , wait * incoming connection */ listen(sockfd,5); clilen = sizeof(cli_addr); while((newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen))) { addlog("connection accepted\n"); pthread_t thread; pthread_attr_t tattr; new_sock =malloc(sizeof(int)); *new_sock = newsockfd; pthread_attr_init(&tattr); pthread_attr_setdetachstate(&tattr,pthread_create_detached); if(pthread_create(&thread,&tattr,doprocessing,new_sock)<0) { addlog("could not create thread\n"); return 1; } addlog("handler assigned\n"); } return 0; } void addlog(char info[300]) { printf("%s",info); return; } void *doprocessing (void* sock_info) { int *sock=(int*)sock_info; int n; char buffer[10000],loginfo[200]; bzero(buffer,10000); n = read(*sock,buffer,10000); if (n < 0) { addlog("error reading socket\n"); exit(1); } sprintf(loginfo,"here message: %s\n",buffer); addlog(loginfo); /* * */ addlog("closing port\n"); close(*sock); addlog("freeing port\n"); free(sock_info); addlog("exiting thread\n"); pthread_exit(null); }
this client code, divide 4 functions, starts, stop, send , receive:
#define connection_started 1 #define connection_not_started 0 #..all return macros here too.. int sockfd; int status=connection_not_started; struct sockaddr_in serv_addr; int socket_start_connection() { addlog("starting connection\n"); if(status==connection_started) return socket_success_connection_open; char *serveraddr=server_hostname;//example.ex int portno,valopt,res; struct hostent *server; struct timeval tv; socklen_t lon; fd_set myset; long arg; sockfd=-1; portno =server_port;//1111 sockfd = socket(af_inet, sock_stream, 0); if (sockfd < 0) { addlog("error opening socket"); return socket_error_opening_port; } server=gethostbyname(serveraddr); if (server == null) { addlog("error no such host"); return socket_error_host_not_found; } bzero((char *) &serv_addr, sizeof(serv_addr)); serv_addr.sin_family = af_inet; bcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr, server->h_length); serv_addr.sin_port = htons(portno); if( (arg = fcntl(sockfd, f_getfl, null)) < 0) { addlog("error fcntl , f_getfl"); return socket_error_timeout_f_getfl; } arg |= o_nonblock; if( fcntl(sockfd, f_setfl, arg) < 0) { addlog("error fcntl, f_setfl"); return socket_error_timeout_f_setfl; } res=connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)); if(res<0) { if(errno==einprogress) { { tv.tv_sec = socket_connection_time_limit;//something 60 seconds tv.tv_usec = 0; fd_zero(&myset); fd_set(sockfd, &myset); res = select(sockfd+1, null, &myset, null, &tv); if (res < 0 && errno != eintr) { addlog("error connecting server"); exit(socket_error_connecting_to_host); } else if (res > 0) { lon = sizeof(int); if (getsockopt(sockfd, sol_socket, so_error, (void*)(&valopt), &lon) < 0) { addlog("error getsockopt"); return socket_error_getsockopt; } // check value returned... if (valopt) { addlog("error in connection server"); socket_stop_connection(); return socket_error_delayed_connection; } break; } else { addlog("error, time limited exceed"); socket_stop_connection(); return socket_error_connection_timeout; } }while(1); } } // set blocking mode again... if( (arg = fcntl(sockfd, f_getfl, null)) < 0) { addlog("error fcntl , f_getfl"); return socket_error_timeout_f_getfl; } arg &= (~o_nonblock); if( fcntl(sockfd, f_setfl, arg) < 0) { addlog("error fcntl , f_setfl"); return socket_error_timeout_f_setfl; } status=connection_started; return socket_success_connection_open; } int socket_stop_connection() { addlog("stopping connection\n"); if(status==connection_not_started) return socket_error_closing_connection; close(sockfd); status=connection_not_started; return socket_success_connection_closed; } int socket_send_message(char* message) { addlog("sending message\n"); if(!status==connection_started) { socket_start_connection(); if(!status==connection_started) { addlog("error not connected"); return socket_error_not_connected; } } int n; n = write(sockfd,message,strlen(message)); if (n < 0) { addlog("error writing socket"); return socket_error_writing_to_socket; } return socket_success_message_sent; } int socket_receive_message(char* buffer) { addlog("receiving message\n"); if(!status==connection_started) { addlog("error not connected"); return socket_error_not_connected; } int n; bzero(buffer,256); n = read(sockfd,buffer,255); if (n < 0) addlog("error reading socket"); close(sockfd); sockfd = socket(af_inet, sock_stream, 0); return socket_success_message_received; }
Comments
Post a Comment