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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> TCP сервер-клиент 
:(
    Опции темы
zhenya1
Дата 26.2.2011, 20:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



У меня явно что-то не в порядке. А в часности: я не понимаю почему после выполнения bind() все ложится, что у меня там не так происходит?

сервер:

Код

int main( void ) 
 { 
 struct sockaddr_in local; 
 SOCKET s; 
 SOCKET s1; 
 int rc=0; 
 char buf[ 1 ] ; 
 local.sin_family = AF_INET; 
 local.sin_port = htons( 7500 ); 
 local.sin_addr.s_addr = htonl( INADDR_ANY ); 
 s = socket( AF_INET, SOCK_STREAM,0 ); 
 if ( s < 0 ) 
 { 
 cout<<"ошибка вызова socket" <<endl; 
system("pause");
}

 rc = bind( s, ( struct sockaddr * )&local, sizeof( local ) ); 
 if ( rc <= 0 ) 
 { 
 cout<<"ошибка вызова bind" <<endl; 
system("pause");
 } 
rc = listen( s, 5 ); 
 if ( rc ) 
 { 
 cout<< "ошибка вызова listen" <<endl; 
system("pause");
  } 
 s1 = accept( s, NULL, NULL ); 
 if ( s1 < 0 ) 
 { 
cout<< "ошибка вызова accept" <<endl; 
system("pause");
  } 
  rc = recv( s1, buf, 1, 0 ); 
if ( rc <= 0 ) 
 { 
cout<< "ошибка вызова recv" <<endl; 
system("pause");
} 
 cout<<b[0];
 rc = send( s1, "2", 1, 0 ); 
if ( rc <= 0 ) 
 cout<< "ошибка вызова send" <<endl; 
system("pause"); 
 }


клиент:

Код

void main( void ) 
{
 struct sockaddr_in peer;  
 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" ); 
 SOCKET s = socket( AF_INET, SOCK_STREAM, 0 ); 
 if ( s < 0 ) 
 { 
 cout<< "Error in call socket" <<endl; system("pause");
  } 
 rc = connect( s, ( struct sockaddr * )&peer, sizeof( peer ) ); 
 if ( rc<=0 ) 
 { 
cout<< "Error in call connect" <<endl;; system("pause");
 }
  rc = send( s, "1", 1, 0 ); 
 if ( rc <=0 ) 
 { 
 cout<< "Error in call send"<<endl; system("pause");
 }
 rc = recv( s, buf, 1, 0 ) ; 
 if ( rc <=0 ) 
 {
 cout<< "Error in call recv"<<endl; system("pause");
 }
 else 
cout<<buf[0];
}


Это сообщение отредактировал(а) Олег2005 - 27.2.2011, 12:04
PM MAIL   Вверх
Олег2005
Дата 27.2.2011, 12:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Завсегдатай
Сообщений: 421
Регистрация: 26.5.2005
Где: Рига Латвия

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



Во первых - что за ОС?
Во вторых - что значит после бинда все ложится?
Бинд не выполняется?
Где анализ кода ошибки?
PM MAIL WWW MSN   Вверх
zhenya1
Дата 27.2.2011, 14:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



 Для простоты и понимания  сдалал UNIX, хотя в конце-концов мне нужно в windows ( я думаю, сильно отличаться не будет ,или я не прав?).
После bind() переменная rc принимает -1 почему-то.

PM MAIL   Вверх
Олег2005
Дата 27.2.2011, 15:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Завсегдатай
Сообщений: 421
Регистрация: 26.5.2005
Где: Рига Латвия

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



-1 - это у всех юниксовых функций почти - просто свидетельство об ошибке.
А вам нужен код ошибки....
Для этой функции в переменной errno определены следующие коды ошибок:
EBADF    – аргумент – недопустимый описатель файла; 
ENOTSOCK    – дескриптор сокета – не сокет;
EADDRNOTAVAIL    – заданный адрес недоступен на этой машине;
EADDRINUSE    – существует другой сокет, использующий заданный адрес;
EINVAL    – сокет еще не был привязан к адресу или уже находится в подключенном состоянии;
EACCESS    – у процесса недостаточно прав для обращения по заданному адресу. 
Без этого кода нельзя выяснить истинную причину.
Это - правило сетевого программирования - всегда исследовать код ошибки....
Насчет Windows
Да, портировать под винду несложно.......
PM MAIL WWW MSN   Вверх
zhenya1
Дата 27.2.2011, 15:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Впервые сталкиваюсь, но я так понял нужно это в тело bind() добавить:
Код

cout<<errno<<endl;cout<<strerror(errno)<<endl;


Если это, то результат: 0 No error
PM MAIL   Вверх
Олег2005
Дата 27.2.2011, 20:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Завсегдатай
Сообщений: 421
Регистрация: 26.5.2005
Где: Рига Латвия

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



Не понял.
Такого кода ошибки просто нет.
Возврат 0 - означает успешное завершение вызова функции. А вот если возврат -1, то то надо смотреть errno
Например:
if(errno == EINPROGRESS) /* EINPROGRESS означает, что функция все еще пытается установить соединение */
{

действие

}
Это проверка для connect()
так какой код возврата bind()?

if ( rc <= 0 ) меньше нуля.....а не равно......
Вызов 
res=bind(sd, name, addrlen);
при корректном выполнении возвращает код 0 (res = 0), в противном случае res = -1.


Это сообщение отредактировал(а) Олег2005 - 27.2.2011, 21:02
PM MAIL WWW MSN   Вверх
zhenya1
Дата 27.2.2011, 22:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Да , у меня rc = -1. 
Но я не понимаю как мне определить  этот код. В Вашем примере вы уже знаете с чем сравнивать:if(errno == EINPROGRESS), а откуда Вы это узнали??
PM MAIL   Вверх
Олег2005
Дата 27.2.2011, 22:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Завсегдатай
Сообщений: 421
Регистрация: 26.5.2005
Где: Рига Латвия

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



Если вы работаете под Юниксом - то это глобальная переменная процесса
Можете ее анализировать
Под виндами - там другая фишка - WSAGetLastError()


PM MAIL WWW MSN   Вверх
zhenya1
Дата 27.2.2011, 23:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Я с этими ошибками и UNIX только свое и Ваше время трачу...
Я попробовал под WIN(кстати, те ли я библиотеки задействовал?) и без всего лишнего, но в результате получаю "левый" символ, а не цифру. Почему? 

серв:
Код


#pragma comment (lib, "ws2_32.lib")
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#include<winsock2.h>
 using namespace std;

void main()
 {
     char buf[1];
SOCKET s = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);

    struct sockaddr_in sin;
    sin.sin_family = AF_INET;
    sin.sin_port = htons(80);
    sin.sin_addr.s_addr = INADDR_ANY;

     int err = bind( s, (LPSOCKADDR)&sin, sizeof(sin) );
     err = listen( s, SOMAXCONN);

    sockaddr_in from;
    int fromlen=sizeof(from);
    SOCKET  s1 = accept(s,(struct sockaddr*)&from, &fromlen);

  err = recv(s1, buf, 1, 0 ); 
  cout<<buf[0];
 err = send( s1, "2", 1, 0 ); 

closesocket(s1);
system("pause");
 }


клиент:

Код

#pragma comment (lib, "ws2_32.lib")
#include <winsock2.h>
#include <iostream>
#include <stdlib.h>
using namespace std;

int main()
{
char buf[1];
int rc;
SOCKET s = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
 
        struct sockaddr_in anAddr;
        anAddr.sin_family = AF_INET;
        anAddr.sin_port = htons(80);
        anAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
 
        connect(s, (struct sockaddr *)&anAddr, sizeof(struct sockaddr));
 
              rc = send( s, "1", 1, 0 ); 
              rc = recv(s, buf, 1, 0 ) ; 
              cout<<buf[0];
            
              closesocket(s);
                system("pause");
                return 0;
}

PM MAIL   Вверх
Олег2005
Дата 1.3.2011, 15:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Завсегдатай
Сообщений: 421
Регистрация: 26.5.2005
Где: Рига Латвия

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



А где
WSADATA и WSAStartup()? WSACleanup()?
PM MAIL WWW MSN   Вверх
zhenya1
Дата 1.3.2011, 21:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Большое спасибо, все заработало!
PM MAIL   Вверх
zhenya1
Дата 8.3.2011, 15:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



У меня сервер должен получить слово и послать результат клиент(полиндром или нет). Но мне кроме рузультата проверки "левые" символы приходят...окуда они? Правильно ли у меня сделано, добавил цикл ( чтобы сервер мог работать с многими, но не одновременно) ?

серв:


Код

int main()
 {
     WORD wVersionRequested;
    WSADATA wsaData;
    wVersionRequested=MAKEWORD(2,2);
    WSAStartup(wVersionRequested,&wsaData);

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

    struct sockaddr_in sin;
    sin.sin_family = AF_INET;
    sin.sin_port = htons(80);
    sin.sin_addr.s_addr = INADDR_ANY;

     int err = bind( s, (LPSOCKADDR)&sin, sizeof(sin) );
     err = listen( s, SOMAXCONN);

for(;;)
{    
         char str[22];
    sockaddr_in from;
    int fromlen=sizeof(from);
    SOCKET  s1 = accept(s,(struct sockaddr*)&from, &fromlen);

  err = recv(s1, str, sizeof(str), 0 ); 
  cout<<str<<endl;
   for(int i=0;i<sizeof(str);i++){
                if(str[i]!=str[sizeof(str)-1-i])
                {
                    err = send( s1, "It`s no!", 7, 0 );
                       
                        system("pause");
                        return 0;
                }
        }
    err = send( s1, "Yes!", 5, 0 );

 closesocket(s1);
    }
        WSACleanup();
system("pause");
 }


клиент:

Код

int main()
{
    WORD wVersionRequested;
    WSADATA wsaData;
    wVersionRequested=MAKEWORD(2,2);
    WSAStartup(wVersionRequested,&wsaData);

int rc;
SOCKET s1 = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
 
        struct sockaddr_in anAddr;
        anAddr.sin_family = AF_INET;
        anAddr.sin_port = htons(80);
        anAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
 
        connect(s1, (struct sockaddr *)&anAddr, sizeof(struct sockaddr));

        for(;;)
        {
                char str[44];
        cout<<"\nEnter word\n";
        cin>>str;

              rc = send( s1, str,sizeof(str), 0 ); 
              rc = recv(s1,str, sizeof(str), 0 ) ; 
              cout<<str;
        }
     closesocket(s1);
                WSACleanup();
                system("pause");
                return 0;
}

PM MAIL   Вверх
Олег2005
Дата 8.3.2011, 17:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Завсегдатай
Сообщений: 421
Регистрация: 26.5.2005
Где: Рига Латвия

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



Принципиально идея верная - у вас получился последовательный сервер - должен обрабатывать всех клиентов последовательно.
PM MAIL WWW MSN   Вверх
zhenya1
Дата 8.3.2011, 18:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Это хорошо, благодарен, но еще одна мелочь: откуда берутся лишние символы при отправке результата клиенту?
PM MAIL   Вверх
Олег2005
Дата 9.3.2011, 19:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Завсегдатай
Сообщений: 421
Регистрация: 26.5.2005
Где: Рига Латвия

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



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


 




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


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

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