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

Ошибка с Socket - не читаем и не пишем

Добавлено: Вт фев 08, 2011 08:28:47
Кислый
Пишу программу для управления МК с компа через RS232, но команды на комп должны приходить с сети. Начал зазбираться с сокетами. И вот загвоздка - непонятная мне ошибка:

Если мы в функции

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

void OpenSock ( int socket, byte nm_socket_msg[] )
{
    socket = connectsock ( SERVER_IP, LS_PORT, "tcp" );

    if(socket < 0)	//проверяем дескриптор сокета
		return;
	else 		//подключились
		{
		    printf("Установлено соединение с %s:%s\n", SERVER_IP, LS_PORT);
		}

// вот тут !!

}
берем и читаем или пишем сокет

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

    Read_Socket(socket, nm_socket_msg, 16);
    Write_Socket(socket, nm_socket_msg, 16);
    CloseSock(socket);
то все типтоп. а если вот так:

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

typedef unsigned char byte; // 0x00 ... 0xFF

    int net_socket;
    byte net_msg[256];

void main(void)
{
    OpenSock(net_socket, net_msg);

    Read_Socket(net_socket, net_msg, 16);
    Write_Socket(net_socket, net_msg, 16);

    CloseSock(net_socket);
}
то все!! крах и тарабах!!! трындец !!! не читаем и не пишем ( о чем сведетельствует переменная n, смотри листинг ниже )

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

void Read_Socket (int socket, byte nm_socket_msg[], int len)
{   int n;
    n = recv(socket, nm_socket_msg, len, 0);
    printf("%i\n", n);
    view_pkt(nm_socket_msg, 1);
}

void Write_Socket (int socket, byte nm_socket_msg[], int len)
{   int n;
    n = send(socket, nm_socket_msg, len, 0);
    printf("%i\n", n);
    view_pkt(nm_socket_msg, 0);
}

void CloseSock (int socket)
{
    close(socket);
    printf("%s", "Соединение разорвано \n");
}

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

//функция подключения к серверу. реализация /не моё/
int connectsock(const char *host, const char *port, const char *transport)
{
    struct hostent *phe; //указатель на запись с информацией о хосте
    struct servent *pse; //указатель на запись с информацией о службе
    struct protoent *ppe; //указатель на запись с информацией о протоколе
    struct sockaddr_in sin; //структура IP-адреса оконечной точки
    int s, type; //дескриптор сокета и тип сокета
 
    //обнуляем структуру адреса
    memset(&sin, 0, sizeof(sin));
    //указываем тип адреса (IPv4)
    sin.sin_family = AF_INET;
    //задаем порт
    sin.sin_port = htons((unsigned short)atoi(port));
    //преобразовываем имя хоста в IP-адрес, предусмотрев возможность представить его
    //в точечном десятичном формате
    if(phe = gethostbyname(host))
        memcpy(&sin.sin_addr, phe->h_addr, phe->h_length);
    //преобразовываем имя транспортного протокола в номер протокола
    if((ppe = getprotobyname(transport)) == 0)
        {
            printf("Ошибка преобразования имени транспортного протокола: %s\n", strerror(errno));   //в случае неудачи выводим сообщение ошибки
            return -1;
        }
    //используем имя протокола для определения типа сокета
    if(strcmp(transport, "udp") == 0)
        type = SOCK_DGRAM;
    else
        type = SOCK_STREAM;
    //создание сокета
    s = socket(PF_INET, type, ppe->p_proto);
    if(s < 0)
        {
            printf("Ошибка создания сокета: %s\n", strerror(errno));    //в случае неудачи выводим сообщение ошибки
            return -1;
        }
    //попытка подключить сокет
    if(connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0)
        {
            printf("Не удалось подключится к серверу: %s\n", strerror(errno));  //в случае неудачи выводим сообщение ошибки
            return -1;
        }
    //возвращаем дескриптор подключенного сокета
    return s;
}

Re: Ошибка с Socket - не читаем и не пишем

Добавлено: Вт фев 08, 2011 08:40:23
Кислый
ошибка понята, но я хз что с ней делать.

Re: Ошибка с Socket - не читаем и не пишем

Добавлено: Вт фев 08, 2011 09:39:52
_AHTOXA_
Кислый писал(а):

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

void OpenSock ( int socket, byte nm_socket_msg[] )
{
    socket = connectsock ( SERVER_IP, LS_PORT, "tcp" );

    if(socket < 0)	//проверяем дескриптор сокета
		return;
	else 		//подключились
		{
		    printf("Установлено соединение с %s:%s\n", SERVER_IP, LS_PORT);
		}
}
Переменная socket передаётся в функцию OpenSock() по значению. Это значит, что все изменения, которые производятся с ней внутри функции, теряются при выходе из неё.
Поэтому надо сделать, например так:

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

void OpenSock (int *socket, byte nm_socket_msg[] )
{
    *socket = connectsock ( SERVER_IP, LS_PORT, "tcp" );

    if(*socket < 0)	//проверяем дескриптор сокета
		return;
	else 		//подключились
		{
		    printf("Установлено соединение с %s:%s\n", SERVER_IP, LS_PORT);
		}
}
То есть, передаём в функцию указатель на переменную для сокета. Функция теперь кладёт по этому адресу результат подключения.
И далее:

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

void main(void)
{
    OpenSock(&net_socket, net_msg);
    if (net_socket>=0)
    {
        Read_Socket(net_socket, net_msg, 16);
        Write_Socket(net_socket, net_msg, 16);
...
Как-то так.

Re: Ошибка с Socket - не читаем и не пишем

Добавлено: Вт фев 08, 2011 10:56:48
kolobok0
Кислый писал(а):...то все!! крах и тарабах!!! трындец !!! не читаем и не пишем ( о чем сведетельствует переменная n, смотри листинг ниже )

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

void Read_Socket (int socket, byte nm_socket_msg[], int len)
{   int n;
    n = recv(socket, nm_socket_msg, len, 0);
    printf("%i\n", n);
    view_pkt(nm_socket_msg, 1);
}
...
....
что конкретнее происходит - опишите.
насколько я понимаю вы иногда получаете n отличное от посылаемой длины? :)

открываем МСДН, внимательно читаем...
TCP - протокол потоковый
если ошибку не видите - повторяете как мантру. потоковый, потоковый, потоковый. пока не снизойдёт озарение!!!
потоковый - это значит что вам никто и не обещал что прийдёт n пример:
послали 10000 (попробуйте кстати - на больших сразу заметно о чём речь.) байт
принимать думаете будете 10000 ? :)
вы можете принять 1000 + 300 + 10 + 8690, а может 3000+5000+1000+500+500 это протоколом НЕ! гарантируется.

надеюсь суть поняли
(круглый)
ЗЫ
Это типичная ошибка с сокетами. Увы такого кода не рабочего в инете пруд пруди. Ударная нагрузка сразу выявит эти траблы.

Re: Ошибка с Socket - не читаем и не пишем

Добавлено: Вт фев 08, 2011 10:59:47
Кислый
нет. если n -1 - то трындец. а прием или передача - максимум по 256 байт

Re: Ошибка с Socket - не читаем и не пишем

Добавлено: Вт фев 08, 2011 11:27:51
kolobok0
Кислый писал(а):нет. если n -1 - то трындец. а прием или передача - максимум по 256 байт

256 - это пока в тепличных условиях работать будет. чуть что посерьёзнее - будет задница.
вам выше правильно сказали - вы передаёте в опен переменныу сокет типа инт. с чего вы взяли что она вернёт вам значение из функции? эта переменная на стэке. стэк при выходе из функции разрушится. вам необходимо передать ссылку(референц) на сокет типа инт, либо указатель на сокет типа инт. и вот тогда работать будет.

но повторюсь - функция приёма у вас левая. постить МСДН сюда не буду - гляньте там. Хоть он и содержит ошибки, но в данном разделе стоит к нему прислушаться. Там рабочий код приведён.

удачи вам
(круглый)

Re: Ошибка с Socket - не читаем и не пишем

Добавлено: Вт фев 08, 2011 12:11:42
Кислый
угу. давайте бить из пушки по комарам :)

Re: Ошибка с Socket - не читаем и не пишем

Добавлено: Ср фев 09, 2011 15:51:49
kolobok0
Кислый писал(а):угу. давайте бить из пушки по комарам :)
в образовательных целях:
на сегоднешний момент времени, есть драйвера (под форточки) которые могут сидеть в сетевой цепочки и отдавать (при необходимости) по байтно.

ваше право делать софт который будет глючить в данных условиях, потому как не правильно используете протокол TCP.

удачи вам
она вам пригодится
(круглый)