Модераторы: feodorv

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> SOCKET: send(), recv() 
:(
    Опции темы
Fantaz1
Дата 18.7.2010, 12:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 44
Регистрация: 16.1.2009

Репутация: нет
Всего: нет



Начал разбираться с сокетами и в самом начале застрял на элементарном, с функциями send и recv, в програмке в которой сервер отправляет сообщения на клиент и там оно выводится на экран...
Вот коды двух программ.
Сервер:
Код

int main()
{
        WORD wVersion;
        WSADATA wsaData;
        int err;
        wVersion = MAKEWORD(1,1);
        err = WSAStartup(wVersion, &wsaData);
        if( err != 0)
                return 0;
 
        if(LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)
        {
                WSACleanup();
                return 0;
        }
 
        SOCKET sServ, sConnSock;
        sockaddr_in addr, CliAddr;
        int addrLen = sizeof(sockaddr);
        
        sServ = socket(AF_INET,SOCK_STREAM, 0);
        
        addr.sin_family = AF_INET;
        addr.sin_port = htons(5000);
        addr.sin_addr.S_un.S_addr = inet_addr("10.0.172.14");
 
        if(bind(sServ, (LPSOCKADDR)&addr, sizeof(addr)) == SOCKET_ERROR)
        {
                printf("ERROR BIND\n");
                system("pause");
                return 0;
        }
 
        if(listen(sServ, 2) == SOCKET_ERROR)
        {       
                printf("ERROR LISTEN\n");
                system("pause");
                return 0;
        }
 
        if(accept(sServ, (LPSOCKADDR)&CliAddr, &addrLen) == INVALID_SOCKET)
        {
                printf("ERROR ACCEPT\n");
                system("pause");
                return 0;
        }
        
        char str[64] = "Message";
 
        while(1)
        {               
                if(send(sServ,(char *)&str,sizeof(str),0) == SOCKET_ERROR)
                {
                        break;
                }
                printf( "C=>S: %s\n",  str);
        }
        
        closesocket(sServ);
        WSACleanup();
        
        system("pause");
        return 0;
}

Клиент:
Код

int main()
{
        WORD wVersion;
        WSADATA wsaData;
        int err;
        wVersion = MAKEWORD(1,1);
        err = WSAStartup(wVersion, &wsaData);
        if( err != 0)
                return 0;
 
        if(LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)
        {
                WSACleanup();
                return 0;
        }
 
        SOCKET sCliSock;
        sockaddr_in ServAddr;
        int addrLen = sizeof(sockaddr);
 
        sCliSock = socket(AF_INET,SOCK_STREAM, 0);
 
        ServAddr.sin_family = AF_INET;
        ServAddr.sin_port = htons(5000);
        ServAddr.sin_addr.S_un.S_addr = inet_addr("10.0.172.14");
 
        if(connect(sCliSock, (SOCKADDR*) &ServAddr, sizeof(ServAddr)) == SOCKET_ERROR)
        {
                printf("ERROR CONNECT\n");
                system("pause");
                return 0;
        }
        
        char recvbuf[64];
 
        while(1) 
        {                  
                if (recv( sCliSock, (char *) &recvbuf, sizeof(recvbuf), 0 ) < 0) 
                {
                        printf( "ERROR!\n");            
                        break;
                }
 
                printf( "S=>C: %s\n",  recvbuf);        
    }
 
        closesocket(sCliSock);
        WSACleanup();   
        system("pause");
        return 0;
}

Кто подскажет в чем ошибка?? Почему не отправляются данные??
PM MAIL   Вверх
SenkraD
Дата 19.7.2010, 08:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 933
Регистрация: 3.2.2006
Где: Украина::Киев

Репутация: 1
Всего: 23



Цитата(Fantaz1 @  18.7.2010,  12:16 Найти цитируемый пост)
if(send(sServ,(char *)&str,sizeof(str),0) == SOCKET_ERROR)

и что вы этим отослать пытаетесь?  64 байта с адресса некого указателя?
Код
//...
if(send(sServ, str, strlen(str), 0) == SOCKET_ERROR)
{
     // ...
}
// ...
В приёме данных почти тот же косяк:
Код
char recvbuf[64] = {0};
while(1) 
{
    int const byteReceived = recv(sCliSock, recvbuf, sizeof(recvbuf), 0);
    if (SOCKET_ERROR == byteReceived) 
    {
        printf( "ERROR!\n");            
        break;
    }
    recvbuf[byteReceived] = '\0'; // нужно для коректного вывода строки

    printf( "S=>C: %s\n",  recvbuf);
}




--------------------
 Имеющий язык - да не убоится спросить! 
user posted image
PM MAIL ICQ   Вверх
Fantaz1
Дата 19.7.2010, 09:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 44
Регистрация: 16.1.2009

Репутация: нет
Всего: нет



SenkraD исправил ваши замечания, но это не помогло:( Все равно зависает на recv()/send().. То есть сразу возвращает SOCKET_ERROR в этих методах.


Это сообщение отредактировал(а) Fantaz1 - 19.7.2010, 09:46
PM MAIL   Вверх
SenkraD
Дата 19.7.2010, 10:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 933
Регистрация: 3.2.2006
Где: Украина::Киев

Репутация: 1
Всего: 23



а что выдаёт GetLastError()?


--------------------
 Имеющий язык - да не убоится спросить! 
user posted image
PM MAIL ICQ   Вверх
Fantaz1
Дата 19.7.2010, 10:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 44
Регистрация: 16.1.2009

Репутация: нет
Всего: нет



в сервере ошибку №10057
в клиенте ошибку №10054

Это сообщение отредактировал(а) Fantaz1 - 19.7.2010, 10:30
PM MAIL   Вверх
SenkraD
Дата 19.7.2010, 11:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 933
Регистрация: 3.2.2006
Где: Украина::Киев

Репутация: 1
Всего: 23



10057:
Код
Socket is not connected. 
A request to send or receive data was disallowed because the socket is not connected and
(when sending on a datagram socket using sendto) no address was supplied. Any other type
of operation might also return this error—for example, setsockopt setting SO_KEEPALIVE
if the connection has been reset.


10054:
Код
Connection reset by peer. 
An existing connection was forcibly closed by the remote host. This normally results if the peer
application on the remote host is suddenly stopped, the host is rebooted, the host or remote network
interface is disabled, or the remote host uses a hard close (see setsockopt for more information
on the SO_LINGER option on the remote socket). This error may also result if a connection was broken
due to keep-alive activity detecting a failure while one or more operations are in progress. Operations
that were in progress fail with WSAENETRESET. Subsequent operations fail with WSAECONNRESET.


так нашёл косяк в серваке:
Код
if(accept(sServ, (LPSOCKADDR)&CliAddr, &addrLen) == INVALID_SOCKET)

нужно
Код
sConnSock = accept(sServ, (LPSOCKADDR)&CliAddr, &addrLen);
if (sConnSock == INVALID_SOCKET)
{
     //....
}
//...
if(send(sConnSock, str, strlen(str), 0) == SOCKET_ERROR)
{
     // ...
}
// ...


Это сообщение отредактировал(а) SenkraD - 19.7.2010, 11:04


--------------------
 Имеющий язык - да не убоится спросить! 
user posted image
PM MAIL ICQ   Вверх
Fantaz1
Дата 19.7.2010, 11:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 44
Регистрация: 16.1.2009

Репутация: нет
Всего: нет



SenkraD СПАСИБО ОГРОМНОЕ добрый человек!!!smile))) все заработало!!!)
PM MAIL   Вверх
hoshin
Дата 4.8.2010, 18:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 17
Регистрация: 10.5.2010

Репутация: нет
Всего: нет



Начал изучать сокеты и так же остановился на самых элементарных вещах.

пример взятый с этой ссылки Секреты поваров компьютерной кухни или ПК: решение проблем, первый примитивный пример клиент-сервер с книги "Снейдер Й. - Эффективное программирование TCP-IP" весгда выдают одни и те же ошибки
error LNK2019: unresolved external symbol __imp__recv@16 referenced in function _main
error LNK2019: unresolved external symbol __imp__send@16 referenced in function _main
error LNK2019: unresolved external symbol __imp__connect@12 referenced in function _main
error LNK2019: unresolved external symbol __imp__socket@12 referenced in function _main
error LNK2019: unresolved external symbol __imp__inet_addr@4 referenced in function _main
 error LNK2019: unresolved external symbol __imp__htons@4 referenced in function _main
C:\Debug\tcp book.exe : fatal error LNK1120: 6 unresolved externals
Build log was saved at "file://c:\\Debug\BuildLog.htm"
book - 7 error(s), 0 warning(s)

и данный пример, который Вы только что разбирали выше так же выдал такие ошибки.

Может кто подскажет, что делаю не так.
Пишу на MSVS 2005.


вот код, который например полностью выписан с книги Снейдера Й., выдает все эти семь ошибок. 


клиент

Код


#include "stdafx.h"
#include <winsock2.h>
#include <windows.h>
#include <stdio.h>
#include <iostream>
using namespace std;

int main()
{
    struct sockaddr_in peer;
    int s;
    int rc;
    char buf[1];

    peer.sin_family = AF_INET;
    peer.sin_port = htons(7500);
    peer.sin_addr.s_addr = inet_addr("127.0.0.1");

    s = (int)socket( AF_INET, SOCK_STREAM, 0);
    if( s < 0 ) 
    {
        perror( "err socket ");
        exit(1);
    }

    rc = connect(s, (struct sockaddr *)&peer, sizeof(peer) );
    if (rc)
    {
        perror( "err connect ");
        exit(1);
    }

    rc = send(s , "1", 1, 0);
    if (rc <= 0)
    {
        perror( "err send ");
        exit(1);
    }

    rc = recv(s, buf, 1, 0);
    if(rc <= 0)
        perror("err recv");
    else
        cout << endl << "buf[0] " << buf[0] << endl;
    exit(0);

}





сервер

Код


#include "stdafx.h"
#include <winsock2.h>
#include <windows.h>
#include <stdio.h>
#include <iostream>
using namespace std;

int main()
{
    struct sockaddr_in local;
    int s; 
    int s1;
    int rc;
    char buf[1];

    local.sin_family = AF_INET;
    local.sin_port = htons(7500);
    local.sin_addr.s_addr = htonl( INADDR_ANY );

    s = (int)socket( AF_INET, SOCK_STREAM, 0);
    if(s < 0)
    {
        perror( "error socket ");
        exit(1);
    }
    
    rc = bind( s, (struct sockaddr *)&local, sizeof(local) );
    if(rc < 0)
    {
        perror("error bind");
        exit(1);
    }

    rc = listen(s, 5);
    if(rc)
    {
        perror("error listen");
        exit(1);
    }

    s1 = (int)accept(s, NULL, NULL);
    if( s1 < 0 )
    {
        perror("error accept");
        exit(1);
    }

    rc = recv(s1, buf, 1, 0);
    if(rc <= 0)
    {
        perror("error recv");
        exit(1);
    }

    cout << "buf[0](serv) " << buf[0] << endl;
    rc = send(s1, "2", 1, 0);
    if(rc <= 0)
        perror("error send");
    exit(0);
}




при игнорировании этих ошибок, выдает сообщение, что

Unable to start program c:\book.exe
 "Не удается найти указаный файл"


Подскажите пожалуйста, что делать...




PM MAIL   Вверх
null56
Дата 4.8.2010, 19:22 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 721
Регистрация: 19.3.2008

Репутация: нет
Всего: 12



это ошибки линковки, надо подключить библиотеку сокетов, посмотри в мсдн, как она называется

Добавлено @ 19:24
добавь в начало кода после инклюдов
Код

#pragma comment(lib,"Ws2_32.lib")



Это сообщение отредактировал(а) null56 - 4.8.2010, 19:26
PM MAIL   Вверх
hoshin
Дата 4.8.2010, 21:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 17
Регистрация: 10.5.2010

Репутация: нет
Всего: нет



Цитата(null56 @ 4.8.2010,  19:22)
это ошибки линковки, надо подключить библиотеку сокетов, посмотри в мсдн, как она называется

Добавлено @ 19:24
добавь в начало кода после инклюдов
Код

#pragma comment(lib,"Ws2_32.lib")

Спасибо тебе Добрый Человек!!!!


только может знаете

в книге автор написал в коде сервера - 

Код


    rc = listen(s, 5);    
    if(rc)
    {
          perror("err listen");
          exit(1);
    }



и в консоли выводится сообщение   "err listen : No error"

посмотрел значение rc и SOCKET_ERROR - 
rc = 4294967295;
SOKET_ERROR = -1;


автор описал функцию listen() так:

int listen(SOCKET s, int backlog);
Возвращаемое значение: SOCKET_ERROR (для Windows) - ошибка.


Подскажите кокое должно быть возвращаемое значение rc и SOCKET_ERROR - которое показывает, что ошибок нет.
или была опечатка, которую надо исправить на if( !rc ) {...};



PM MAIL   Вверх
Modul
Дата 4.8.2010, 23:00 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 238
Регистрация: 17.2.2006

Репутация: нет
Всего: нет



Цитата

Подскажите кокое должно быть возвращаемое значение rc и SOCKET_ERROR - которое показывает, что ошибок нет.
или была опечатка, которую надо исправить на if( !rc ) {...};


При возникновении ошибки listen() возвращает -1, SOCKET_ERROR = -1.

Код

if (listen(sockfd, BACKLOG) == -1) 

            perror("listen"); 
            exit(1); 


--------------------
I'll be back !
PM MAIL   Вверх
hoshin
Дата 5.8.2010, 13:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 17
Регистрация: 10.5.2010

Репутация: нет
Всего: нет



Цитата(Modul @ 4.8.2010,  23:00)
Цитата

Подскажите кокое должно быть возвращаемое значение rc и SOCKET_ERROR - которое показывает, что ошибок нет.
или была опечатка, которую надо исправить на if( !rc ) {...};


При возникновении ошибки listen() возвращает -1, SOCKET_ERROR = -1.

Код

if (listen(sockfd, BACKLOG) == -1) 

            perror("listen"); 
            exit(1); 




тогда, из-за чего получается так, что выражение ( rc == -1 ), является истинным

пример 1.
Код

  rc = listen(sockfd, BACKLOG);
  if( rc == -1 ) 
  { 
            perror("listen"); 
            exit(1); 
  } 



 или как предлагал Modul, так же выражение  (listen(sockfd, BACKLOG) == -1)  является истинным

пример 2.
Код


  if (listen(sockfd, BACKLOG) == -1)  
  { 
            perror("listen"); 
            exit(1); 
  } 




, а когда пишу вот так

пример 3.
Код

if(rc < 0)
  { 
            perror("listen"); 
            exit(1); 
  } 


выражение (rc < 0) не является истинным, т.е. тут rc > 0...

когда решил проверить значение rc и получил такой ответ
cout << "rc = " << rc; //  rc = 4294967295;
 

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



P.S.

после этого примера полностью запутался

Код


              SOCKET rc;
              rc = listen(s, 5);
    if(rc < 0 || rc == -1)
    {
        perror("err listen");
        exit(1);
    }



выражение оператора if(rc < 0 || rc == -1) тут является истинным, тогда почему if(rc < 0) не является истинным (теретий пример)...


PM MAIL   Вверх
SenkraD
Дата 5.8.2010, 14:06 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 933
Регистрация: 3.2.2006
Где: Украина::Киев

Репутация: 1
Всего: 23



hoshin,  ну в последнем случае у вас if сработает если хотя бы одно условия сработает!!!
Какой тип имеет rc? не unsigned xxx часом? - если да, то тогда всё понятно: он никогда не может быть меньше нуля, а проверку равентсва проходит из-за того, что -1 автоматом кастуется к unsigned типу


--------------------
 Имеющий язык - да не убоится спросить! 
user posted image
PM MAIL ICQ   Вверх
Modul
Дата 5.8.2010, 14:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 238
Регистрация: 17.2.2006

Репутация: нет
Всего: нет



В режиме слушания сервера (listen) эта функция возвращает 0, при возникновении ошибки =-1.

Вопросы отпали ???

Вот так правильно:
Код

if (listen(socketfd, 5) == SOCKET_ERROR)
{
fprintf(stderr, "LISTEN...\n"); 
exit(1);
}


или

Код

if (listen(socketfd, 5))
{
fprintf(stderr, "LISTEN...\n"); 
exit(1);
}



Это сообщение отредактировал(а) Modul - 5.8.2010, 15:14
--------------------
I'll be back !
PM MAIL   Вверх
hoshin
Дата 5.8.2010, 14:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 17
Регистрация: 10.5.2010

Репутация: нет
Всего: нет



Цитата(SenkraD @ 5.8.2010,  14:06)
hoshin,  ну в последнем случае у вас if сработает если хотя бы одно условия сработает!!!
Какой тип имеет rc? не unsigned xxx часом? - если да, то тогда всё понятно: он никогда не может быть меньше нуля, а проверку равентсва проходит из-за того, что -1 автоматом кастуется к unsigned типу


во всех примерах rc имеет тип SOCKET, хотя в книге был int,

изменли int на SOCKET, из-за того, что 

Код

 int s;
 s = socket( AF_INET, SOCK_STREAM, 0);


мой компилятор ругался
c:\serv.cpp(22) : warning C4244: '=' : conversion from 'SOCKET' to 'int', possible loss of data

но когда изменил int s на SOCKET s, перестал ругаться...

или когда делая так
Код

 int s;
 s = (int)socket( AF_INET, SOCK_STREAM, 0);

так же переставал ругаться


как надо правильно, так?
пример 1.
Код

 int s;
 s = (int)socket( AF_INET, SOCK_STREAM, 0);


или так?
пример 2.
Код

 SOCKET s;
 s = socket( AF_INET, SOCK_STREAM, 0);


есть ли между этими двумя примерами существенная разница?

PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Сети | Следующая тема »


 




[ Время генерации скрипта: 0.0608 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.