LINUX.ORG.RU

Непонятки с сокетами


0

0

Есть функция которая устанавливает TCP соединение. Функция работает до тех пор пока не будет успешно установлено соединение, причем connect используется вместе с timeout. В целом функция работает хорошо, но если отключить сеть serivce network stop и запустить программу которая вызовет функцию make_connection, то make_connection войдёт в цикл установления соединениея. Если в процессе работы подключить сеть снова 
service network start, то make_connection установит соединение но, при попытке операции send или recv на сокете я получаю Broken pipe. Причем если просто выдераю пачкорд из розетки, то тогда make_connection даже после втыкания шнура обратно не может соединится какое-то время. А telnet же работает всегда и без гемора, подключаясь к тому же сервису, куда я пытаюсь подключиться из make_connection. Может кто подскажет где засада?

int make_connection(char *host, unsigned int port)
{
    int sock, res, lon, valopt, rv;
    struct sockaddr_in addr;
    struct timeval tv, tv2;
    long arg;
    fd_set write_set;
    struct hostent *hp;

    while (1) {
	// create socket
	sock = socket(AF_INET, SOCK_STREAM, 0);

	// set non-bloking mode
	arg = fcntl(sock, F_GETFL, NULL);
	arg |= O_NONBLOCK;
	fcntl(sock, F_SETFL, arg);

	addr.sin_family = AF_INET;
	addr.sin_port = htons(port);

	if ((hp = gethostbyname(host)) != NULL)
	  {
	    printf("resolve host %s succesfully\n", host);
	    memcpy ((char *)&addr.sin_addr,hp->h_addr,hp->h_length);
	  }
	else
	  {
	    addr.sin_addr.s_addr = inet_addr(host);
	    printf("Can't resolve host, using inet_addr\n");
	  }


	printf("Trying to connect...\n");
	res = connect(sock, (struct sockaddr *) &addr, sizeof(addr));
	printf("res = %d\n", res);

	if (res < 0)
	  {
	    if (errno == EINPROGRESS) // was (errno = EINPROGRESS)
	      {
		perror("connect");
		printf("EINPROGRESS\n");
	        tv.tv_sec = 10;
	        tv.tv_usec = 0;
	        FD_ZERO(&write_set);
	        FD_SET(sock, &write_set);
	        if ((rv = select(sock + 1, NULL, &write_set, NULL, &tv)) > 0)
		  {
		    getsockopt(sock, SOL_SOCKET, SO_ERROR, (void*)&valopt, (socklen_t*)&lon);
		    if (valopt)
		      {
			printf("Error - valopt\n");
		      } else break;
		  } else {
		  printf("Timeout\n");
	        }
	      } else {
	      printf("Error in connect\n");
	    }
	  }
	close(sock);
	sleep(5);
    }

    arg = fcntl(sock, F_GETFL, NULL);
    arg &= (~O_NONBLOCK);
    fcntl(sock, F_SETFL, arg);

    tv2.tv_sec = 50;
    tv.tv_usec = 0;

    lon = sizeof(int);
    setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, &tv2, sizeof(tv2));
    setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv2, sizeof(tv2));

    return sock;
}

anonymous

Неотформатировал текст в вопросе, сори.

Есть функция которая устанавливает TCP соединение. Функция работает до тех пор пока не будет успешно установлено соединение, причем connect используется вместе с timeout. В целом функция работает хорошо, но если отключить сеть serivce network stop и запустить программу которая вызовет функцию make_connection, то make_connection войдёт в цикл установления соединениея. Если в процессе работы подключить сеть снова service network start, то make_connection установит соединение но, при попытке операции send или recv на сокете я получаю Broken pipe. Причем если просто выдераю пачкорд из розетки, то тогда make_connection даже после втыкания шнура обратно не может соединится какое-то время. А telnet же работает всегда и без гемора, подключаясь к тому же сервису, куда я пытаюсь подключиться из make_connection. Может кто подскажет где засада?

anonymous
()
Ответ на: комментарий от anonymous

1) попробуйте создавать сокет вне цикла.

2) поиграйтесь со значениями таймаута. для non-blocking sockets его значение можно вальировать.

asgard
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.