Страница 1 из 1

Сокеты и время простоя

Добавлено: 2009-09-09 7:01:47
helloworld
Это часть кода клиента, который соединяется с сервером через сокет.

Что хочу: после посылки сообщения, если в течении 3 секунд не пришел обратное сообщение(ACK) от сервера(что мессадж получен), то послать еще раз первое сообщение, если второй раз не будет ответа от сервера - написать до свидания, закрыть сокет и выдти.

Где то туплю не могу понять.

Код: Выделить всё


	char testmsg[] = "hello moto";

	/* send a message to the server PORT on machine HOST */
	if (send(sd, testmsg, sizeof(testmsg), 0) == -1) {
		perror("send");
		exit(1);
	}
	fd_set readFd;
	struct timeval timeout;
	timeout.tv_sec = 3;
	timeout.tv_usec = 0;

	do	
	{
		FD_ZERO(&readFd);
		FD_SET(sd, &readFd);
		select(255,&readFd, NULL, NULL, &timeout);
	
	
		if ( FD_ISSET(sd, &readFd)==1)
		{
			char echobuf[4096];
		
			n = recv(sd, echobuf, sizeof(echobuf),0);
			if (n>0)
			{
				printf("echo buf is: %s\n",echobuf);
			}
		}
		else
		{	
			printf("Sending second time...\n");
			if (send(sd, testmsg, sizeof(testmsg), 0) == -1)
			{
				perror("send");
				exit(1);
			}
		
			if ( FD_ISSET(sd, &readFd)==1)
			{
				char echobuf[4096];
		
				n = recv(sd, echobuf, sizeof(echobuf),0);
				if (n>0)
				{
					printf("echo buf is: %s\n",echobuf);
				}
				else
				{
					printf("I'm sorry, I did not receive any ACK, I'm shutting down...\n");
					close(sd);
					exit(1);
				}
			}
		
				
		}
	} while (n>0);


Re: Сокеты и время простоя

Добавлено: 2009-09-09 10:42:45
paradox
конечно

Код: Выделить всё

man select

Re: Сокеты и время простоя

Добавлено: 2009-09-09 17:54:10
helloworld
Спасибо почитал.
А вот как это реализовать там не написано :)
Проблема в том, что после первого else, fd_isset "не желает" ждать еще доп. 3 секунды.
Стоит ли создать при помощи memcpy, еще один tempread файл дескриптор и работать с ним после первого else?

Re: Сокеты и время простоя

Добавлено: 2009-09-09 17:58:58
paradox
select(255,&readFd, NULL, NULL, &timeout);
кто такой 255
когда по мануалу это должен быть fd+1
почему нет анализа возврата значения select ?
там может быть критическая ситуация -1 к примеру

ну и пример выполнения программы покажи а то тяжело понять что там и как на словах

Re: Сокеты и время простоя

Добавлено: 2009-09-09 19:14:08
helloworld
Разобрался.

Код: Выделить всё

	fd_set readFd;
	struct timeval timeout;
	timeout.tv_sec = 3;
	timeout.tv_usec = 0;

		
	
	FD_ZERO(&readFd);
	FD_SET(sd, &readFd);
	
	retval = select(sd+1,&readFd, NULL, NULL, &timeout); 
	if (retval == -1)
	{
		perror("select() 1");
	}
	if (FD_ISSET(sd, &readFd)==1)

	{
		char echobuf[4096];
		n = recv(sd, echobuf, sizeof(echobuf),0);
		printf("n is %d\n",n);
		if (n>0)
		{
			printf("echo buf is: %s\n",echobuf);
		}
		close(sd);
		exit(1);	
	}
	else
	{
		printf("No ACK, Sending second time...\n");
	
		if (send(sd, testmsg, sizeof(testmsg), 0) == -1)
		{
			perror("send");
			exit(1);
		}
	}
	
	struct timeval timeout2;
	timeout2.tv_sec = 3;
	timeout2.tv_usec = 0;


	retval = select(sd+1, &readFd, NULL, NULL, &timeout2);
	if (retval == -1)
	{
		perror("select() 2");
	}
	if (FD_ISSET(sd, &readFd)==1)

	{
		char echobuf[4096];
		n = recv(sd, echobuf, sizeof(echobuf),0);
		if (n>0)
		{
			printf("echo buf is: %s\n",echobuf);
		}
		printf("Got the message, shutting down\n");
		close(sd);
		exit(1);
	}
	else 
	{
		printf("I'm sorry, I did not receive any ACK, ------>> shutting down...\n");
		close(sd);
		exit(1);
	}


Re: Сокеты и время простоя

Добавлено: 2009-09-09 19:16:16
paradox
помоему второй селект и ниже - лишнее
достаточно for до двух