Форум программистов, компьютерный форум, киберфорум
C++: Сети
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.57/7: Рейтинг темы: голосов - 7, средняя оценка - 4.57
32 / 32 / 3
Регистрация: 04.04.2010
Сообщений: 414
1

Обрезается сообщение в системе: клиент - сервер

03.07.2012, 12:38. Показов 1281. Ответов 9
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Изучаю "Самоучитель игры на WINSOCK".
Использую пример TCP клиента и сервера, при отправке сообщение серверу, оно возвращается уже обрезанным. Максимальное количество символов - 13. Как увеличить объем сообщения?

Клиент
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#define PORT 666
#define SERVERADDR "127.0.0.1"
int main()
{
    system("chcp 1251 > nul");
    char buff[1024];
    cout << "TCP DEMO-CLIENT\n";
 
    if ( WSAStartup( 0x202, ( WSADATA* ) &buff[0]))
    {
        cout << "WSAStart error\n";
        return -1;
    }
 
    ///###Создание сокета###
    SOCKET my_sock;
    my_sock = socket(AF_INET,SOCK_STREAM,0);
    if ( my_sock < 0 )
    { 
        cout << "Soscket eroor\n";
        return -1;
    }
 
    ///###Установка соединения###
    sockaddr_in dest_addr;
    dest_addr.sin_family = AF_INET;
    dest_addr.sin_port = htons( PORT );
    HOSTENT *hst;
 
    //преобразование IP адреса из символьного в сетевой формат
    if ( inet_addr( SERVERADDR ) != INADDR_NONE )
        dest_addr.sin_addr.s_addr = inet_addr( SERVERADDR );
    else
        // попытка получить IP адрес по доменному имени сервера
        if ( hst = gethostbyname( SERVERADDR ))
            (( unsigned long* )&dest_addr.sin_addr)[0] =
                ((unsigned long**)hst->h_addr_list)[0][0];
        else
        {
            cout << "Invalid address\n";
            closesocket( my_sock );
            WSACleanup();
            return -1;
        }
    // адрес сервера получен - пытаемся установить соединение
    if ( connect(my_sock,(sockaddr*)&dest_addr,sizeof(dest_addr)))
    {
        cout << "Connect error\n";
        return -1;
    }
 
    cout << " Соединение с сервером успешно установлено\n";
 
    //###Чтение и передача сообщений###
    int nsize;
    while ((nsize = recv(my_sock,&buff[0],sizeof(buff)-1,0))!=SOCKET_ERROR)
    {
        // ставим завершающий ноль в конце строки
        buff[nsize] = 0;
        // выводим на экран
        cout << "S=>C:" << buff << endl;
        // читаем пользовательский ввод с клавиатуры
        cout << "S<=C:";
        fgets( &buff[0], sizeof(buff)-1, stdin);
        // проверка на 'quit'
        if (!strcmp(&buff[0], "quit\n"))
        {
            // корректный выход
            cout << "Exit...";
            closesocket(my_sock);
            WSACleanup();
            return 0;
        }
 
        // передаем строку клиента серверу
        send(my_sock,&buff[0],nsize,0);
    }
    cout << "Recv error\n";
    closesocket(my_sock);
    WSACleanup();
    return -1;
}
Сервер
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#define MY_PORT 666     // Порт, который слушает сервер
 
// макрос для печати количества активных пользователей
#define PRINTUSERS if (nclients) cout << "User on-line: " << nclients << endl; else cout << "No User on-line\n";
 
// прототип функции, обслуживающий подключившихс пользователей
DWORD WINAPI SexToClient(LPVOID client_socket);
 
// глобальная переменная - количество активных пользователей
int nclients = 0;
 
int main ( )
{
    system("chcp 1251 > nul");
    char buff[1024];    // буфер для различных нужд
 
    cout << "TCP ECHO-DEMO-SERVER\n";
 
    if (WSAStartup(0x0202, (WSADATA*) &buff[0]))
    {
        // Ошибка!
        cout << "Error WSAStartup\n";
        return -1;
    }
    
    // ###Создание сокета###
    SOCKET mysocket;
    // AF_INET  - сокет Интернета
    // SOCK_STREAM - потоковый сокет (с установкой соединения)
    // 0 по умолчанию выбирается TCP протокол
    if ( ( mysocket = socket(AF_INET,SOCK_STREAM,0) ) < 0 )
    {
        // Ошибка!
        cout << "Error socket\n";
        WSACleanup();
        return -1;
    }
    
    // ###Связывание сокета с локальным адресом###
    sockaddr_in local_addr;
    local_addr.sin_family = AF_INET;
    local_addr.sin_port = htons( MY_PORT);
    local_addr.sin_addr.s_addr = 0;
 
    // вызываем bind для связывания
    if ( bind( mysocket, ( sockaddr* ) &local_addr, sizeof( local_addr )))
    {
        // Ошибка!
        cout << "Error bind\n";
        closesocket( mysocket );
        WSACleanup();
        return -1;
    }
    
    // ###Ожидание подключений###
    // размер очереди - 0x100
    if ( listen( mysocket, 0x100 ))
    {
        // Ошибка!
        cout << "Error listen\n";
        closesocket( mysocket );
        WSACleanup();
        return -1;
    }
 
    cout << "Ожидание подключений...\n";
 
    // ###Извлекаем сообщение из очереди###
    SOCKET client_socket;       // сокет для клиента
    sockaddr_in client_addr;    // адрес клиента ( заполняетс системой )
 
    // функции accept необходимо передать размер структуры
    int client_addr_size = sizeof( client_addr );
 
    // цикл извлечения запросов на подключение из очереди
    while ( (client_socket = accept( mysocket, ( sockaddr* ) &client_addr, &client_addr_size )))
    {
        nclients++;
 
        // пытаемся получить имя хоста
        HOSTENT *hst;
        hst = gethostbyaddr( ( char* ) &client_addr.sin_addr.s_addr, 4, AF_INET );
 
        // вывод сведений о клиенте 
        cout << "New connect!\n";
        cout << (hst)?hst->h_name : "unname" , inet_ntoa( client_addr.sin_addr );
        PRINTUSERS
        DWORD thID;
        CreateThread( NULL, NULL, SexToClient, &client_socket, NULL, &thID );
    }
    return 0;
}
 
 
// Эта ф-я обслуживает очередного подключившегося клиента
// независимо от остальных
DWORD WINAPI SexToClient( LPVOID client_socket)
{
    SOCKET my_sock;
    my_sock = (( SOCKET*) client_socket)[0];
    char buff[20*1024];
    #define sHELLO "Hello, user\n"
 
    // отправляем клиенту приветствие
    send( my_sock, sHELLO , sizeof( sHELLO ), 0 );
 
    // цикл эхо-сервеа: прием строки от клиента и возвращение ее клиенту
    int bytes_recv;
    while ((bytes_recv = recv( my_sock, &buff[0], sizeof(buff), 0 )) &&
    bytes_recv != SOCKET_ERROR)
    send (my_sock, &buff[0], bytes_recv, 0 );
 
    // соендинение с клиентом разорвано т.к. вышли из цикла while
    nclients--;
    cout << "Disconnect\n";
    PRINTUSERS
 
    closesocket( my_sock );
    return 0;
}
Добавлено через 14 часов 41 минуту

Не по теме:

Как же долго помощь идет:cry:

0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
03.07.2012, 12:38
Ответы с готовыми решениями:

Обмен данными между двумя приложениями по системе клиент-сервер
Всем доброго времени суток. Хочу сразу же уточнить, что готовый код меня не интересует. Нужны...

Взаимодействие WinCC с Labview 2013, как сервер-клиент, так и клиент-сервер
Здравствуйте. Интересует информация о взаимодействии WinCC с Labview 2013, как сервер-клиент, так и...

Чат "Сервер-клиент". На сервер не могу отправить сообщение с клиента
Не могу понять как сделать, чтоб сервер ещё прослушивал и сообщения... Нет ли входящих данных....

Клиент-сервер в один клик!(элемет сервер, клиент)
Вот решил поделиться с вами своей идеей и её реализацией. Всегда написание Сервера и Клиента к...

9
Эксперт С++
4985 / 3092 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
03.07.2012, 13:03 2
Пример обрезания покажи.

C
1
2
3
4
5
6
7
...
char buff[1024];
...
if ( WSAStartup( 0x202, ( WSADATA* ) &buff[0]))
...
while ((nsize = recv(my_sock,&buff[0],sizeof(buff)-1,0))!=SOCKET_ERROR)
...
Что тебе мешает объявить WSADATA для WSAStartup ?
1
32 / 32 / 3
Регистрация: 04.04.2010
Сообщений: 414
03.07.2012, 13:16  [ТС] 3
Цитата Сообщение от lazybiz Посмотреть сообщение
Пример обрезания покажи.
TCP DEMO-CLIENT
Соединение с сервером успешно установлено
S=>C:Hello, user

S<=C:12345678901234567
S=>C:1234567890123
S<=C:aaaaaaaaaaaaaaaaaaaaaa
S=>C:aaaaaaaaaaaaa
S<=C:good
S=>C:good

S<=C:
Цитата Сообщение от lazybiz Посмотреть сообщение
Что тебе мешает объявить WSADATA для WSAStartup ?
Для чего это и как это сделать?
0
Эксперт С++
4985 / 3092 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
03.07.2012, 13:22 4
Цитата Сообщение от gore-lykovoe Посмотреть сообщение
Для чего это и как это сделать?
Для того что в WSAStartup надо передавать адрес специальной структуры WSADATA, а не то что захочется.
C
1
2
WSADATA wsaData;
WSAStartup( MAKEWORD(2, 2), &wsaData );
Еще пример: http://msdn.microsoft.com/en-u... 85%29.aspx
1
32 / 32 / 3
Регистрация: 04.04.2010
Сообщений: 414
03.07.2012, 13:51  [ТС] 5
Цитата Сообщение от lazybiz Посмотреть сообщение
Для того что в WSAStartup надо передавать адрес специальной структуры WSADATA, а не то что захочется.
тоесть в учебнике неправильно было?

Но я так понял, это не повлияет на мою проблему?
0
Эксперт С++
4985 / 3092 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
03.07.2012, 14:00 6
Цитата Сообщение от gore-lykovoe Посмотреть сообщение
тоесть в учебнике неправильно было?
Да.
Цитата Сообщение от gore-lykovoe Посмотреть сообщение
Но я так понял, это не повлияет на мою проблему?
Не знаю, возможно и повлияет, для начала надо исправить хотя бы это.
0
1259 / 650 / 44
Регистрация: 06.02.2011
Сообщений: 1,654
03.07.2012, 14:14 7
Смотрите внимательно на свой клиент:
while ((nsize = recv(my_sock,&buff[0],sizeof(buff)-1,0))!=SOCKET_ERROR)
...
send(my_sock,&buff[0],nsize,0);
1
32 / 32 / 3
Регистрация: 04.04.2010
Сообщений: 414
03.07.2012, 14:24  [ТС] 8
Цитата Сообщение от lazybiz Посмотреть сообщение
для начала надо исправить хотя бы это
исправил для клиента и сервера - все равно обрезает((((

Добавлено через 7 минут
g_u_e_s_t, да, действительно, увеличел nsize при отправке и размер сообщения увеличился тоже, но почему программа из учебника не контролирует размер nsize?
Что делает этот код? Объясните пожалуйста
C++
1
nsize = recv(my_sock,&buff[0],sizeof(buff)-1,0))
0
1259 / 650 / 44
Регистрация: 06.02.2011
Сообщений: 1,654
03.07.2012, 14:32 9
Цитата Сообщение от gore-lykovoe Посмотреть сообщение
g_u_e_s_t, да, действительно, увеличел nsize при отправке и размер сообщения увеличился тоже
Нужно не увеличивать nsize, а отправлять ровно столько сколько ввел пользователь, strlen() туда так и просится.
Цитата Сообщение от gore-lykovoe Посмотреть сообщение
но почему программа из учебника не контролирует размер nsize?
Вы так спрашиваете, будто это я какой-то учебник написал
1
Эксперт С++
2924 / 1274 / 114
Регистрация: 27.05.2008
Сообщений: 3,465
03.07.2012, 14:40 10
Этот код принимает из сокета my_sock сообщение (или его часть), кладет в буфер buff и возвращает количество прочитанных из сокета байт.
Обрати внимание: никто не гарантирует, что за одно обращение к функции recv ты прочитаешь из сокета все соообщение сразу. Ты можешь получить только его часть. Оставшиеся части ты получишь при следующих обращениях к recv, и их надо будет "склеить" вместе для получения полного текста сообщения. Таково уж устройство протокола TCP.
Как уж ты разберешься, где у тебя заканчивается одно сообщение (например, "мама мыла раму"), и начинается другое ("саша ела кашу") - это вопрос твоего прикладного логического протокола, работающего поверх TCP.
1
03.07.2012, 14:40
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
03.07.2012, 14:40
Помогаю со студенческими работами здесь

TCP клиент -сервер, не отправляется сообщение клиентам
Приветствую. Нужно написать клиент-сервер, используя сокеты. Написал сервер и клиент, клиент видит...

Сообщение между независимыми одинаковыми программами, Многопоточка или Клиент-Сервер
Возникла такая проблема. Моя программа читаем письма с почтового ящика, записывает их в базу ms sql...

Клиент-Серверное приложение. Как сделать, чтобы сервер сам отправлял сообщения на клиент
Добрый день всем. Проблема заключается в следующем: Есть клиент-серверное приложение, хочу...

Клиент-серверное приложение. Сервер - ПК, клиент - телефон (Android)
Здравствуйте, решил для обучения написать программу для выключения ПК с телефона, используя...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru