我在c中的异步套接字服务器上遇到了一些麻烦,我把它移到了java,但首先我要解决这个问题。
我为每个连接(不是客户端)都有一个分离的线程,当它完成它关闭它时,我在服务器同时获得2个连接时遇到问题,它有点留下旧的并且从新的开始...
这是代码:
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 to 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);
/* Now bind the 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);
}
/* Now start listening for the clients, here
* process will go in sleep mode and will wait
* for the 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 from socket\n");
exit(1);
}
sprintf(logInfo,"Here is the message: %s\n",buffer);
addLog(logInfo);
/*
* do something
*/
addLog("Closing port\n");
close(*sock);
addLog("freeing port\n");
free(sock_info);
addLog("exiting thread\n");
pthread_exit(NULL);
}
这是我的客户端代码,我将它除以4个函数,启动,停止,发送和接收:
#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)
{
do
{
tv.tv_sec = SOCKET_CONNECTION_TIME_LIMIT;//something like 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 to 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 the value returned...
if (valopt)
{
addLog("Error in connection to 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 to 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 to 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 from socket");
close(sockfd);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
return SOCKET_SUCCESS_MESSAGE_RECEIVED;
}