Форум программистов, компьютерный форум, киберфорум
C++: Сети
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.53/15: Рейтинг темы: голосов - 15, средняя оценка - 4.53
1 / 1 / 0
Регистрация: 26.11.2017
Сообщений: 166

Клиент посылает строку, а сервер заменяет каждый 4 символ на %

11.10.2018, 20:42. Показов 3141. Ответов 5
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Серверная часть
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
#include "stdafx.h"
#include <winsock2.h>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#pragma comment(lib, "ws2_32.lib")
 
using namespace std;
 
int main() {
    WORD wVersionRequested;
    WSADATA wsaData;
    wVersionRequested = MAKEWORD(2, 2);
    WSAStartup(wVersionRequested, &wsaData);
    SOCKET s = socket(AF_INET, SOCK_STREAM, 0);
    struct sockaddr_in local;
    local.sin_family = AF_INET;
    local.sin_port = htons(1280);
    local.sin_addr.s_addr = htonl(INADDR_ANY);
    int c = bind(s, (struct sockaddr*)&local, sizeof(local));
    int r = listen(s, 5);
    while (true) {
        char buf[255], res[100], b[255], *Res;
        //структура определяет удаленный адрес, 
        //с которым  соединяется сокет 
        sockaddr_in remote_addr;
        int size = sizeof(remote_addr);
        SOCKET s2 = accept(s, (struct sockaddr*)&remote_addr, &size);
        while (recv(s2, b, sizeof(b), 0) != 0) {
            int i = 0;
            for (unsigned j = 0; j <= strlen(b); j++)
                if (b[j] == 'a') i++;
            _itoa(i, res, 10);
            Res = new char[strlen(res) + 1];
            strcpy(Res, res);
            Res[strlen(res)] = '\0';
            //Посылает данные на соединенный сокет 
            send(s2, Res, sizeof(Res) - 2, 0);
        }
        closesocket(s2);
    }
    WSACleanup();
}
Клиентская
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
#include "stdafx.h"
#include <winsock2.h> 
#include <iostream> 
#include <stdio.h>
#include <stdlib.h> 
#pragma comment(lib, "ws2_32.lib")
 
using namespace std;
 
int main() {
    WORD wVersionRequested;
    WSADATA wsaData;
    wVersionRequested = MAKEWORD(2, 2);
    WSAStartup(wVersionRequested, &wsaData);
    struct sockaddr_in peer;
    peer.sin_family = AF_INET;
    peer.sin_port = htons(1280);
    //т.к.клиент и сервер на одном компьютере,
        //пишем адрес 127.0.0.119
        peer.sin_addr.s_addr = inet_addr("127.0.0.1");
    SOCKET s = socket(AF_INET, SOCK_STREAM, 0);
    connect(s, (struct sockaddr*) &peer, sizeof(peer));
    char buf[255], b[255];
    cout << "Enter the string, please" << endl;
    cin.getline(buf, 100, '\n');
    send(s, buf, sizeof(buf), 0);
    if (recv(s, b, sizeof(b), 0) != 0) {
        b[strlen(b)+1] = '\0'; 
        for (int i = 3; i < strlen(b); i += 4) {
            b[i] = '%';
        }
            cout << b << endl;
    }
    closesocket(s);
    WSACleanup();
    system("pause");
    return 0;
}
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
11.10.2018, 20:42
Ответы с готовыми решениями:

Написать программу, которая каждый встречающийся в строке заданный символ заменяет на заданную последовательность символов, расширяя при этом строку.
Решите Пожалуйста !!!

Написать программу, которая каждый встречающийся в строке заданный символ заменяет на заданную последовательность символов, расширяя при этом строку
помогите пожалуйста парни задачу решить!!!.задача: Написать программу, которая каждый встречающийся в строке заданный символ заменяет на...

Написать программу, которая каждый встречающийся в строке заданный символ заменяет на заданную последовательность символов, расширяя при этом строку
Написать программу, которая каждый встречающийся в строке заданный символ заменяет на заданную последовательность символов, расширяя при...

5
Любитель чаепитий
 Аватар для GbaLog-
3745 / 1801 / 566
Регистрация: 24.08.2014
Сообщений: 6,020
Записей в блоге: 1
12.10.2018, 05:37
и в чём проблема?
0
1 / 1 / 0
Регистрация: 26.11.2017
Сообщений: 166
12.10.2018, 11:50  [ТС]
Не работает. Я не могу реализовать замену
0
Любитель чаепитий
 Аватар для GbaLog-
3745 / 1801 / 566
Регистрация: 24.08.2014
Сообщений: 6,020
Записей в блоге: 1
15.10.2018, 13:37
в шапке написано: "Клиент посылает строку, а сервер заменяет каждый 4 символ на %".
у вас заменяет клиент.
C++
1
2
3
4
5
6
7
8
9
10
11
while (recv(s2, b, sizeof(b), 0) != 0) {
    int i = 0;
    for (unsigned j = 0; j <= strlen(b); j++)
        if (b[j] == 'a') i++;
    _itoa(i, res, 10);
    Res = new char[strlen(res) + 1];
    strcpy(Res, res);
    Res[strlen(res)] = '\0';
    //Посылает данные на соединенный сокет 
    send(s2, Res, sizeof(Res) - 2, 0);
}
всё, что тут происходит: считается кол-во букв 'a' в полученном буфере и посылается назад это число.
т.к. буфер b не инициализирован и не заполнен нулями, strlen(b) может выдать полную чушь, что может привести к странным результатам.

сразу уточню: это ваш код или вы его нашли и вам просто нужно его модифицировать под вашу задачу?
1
Эксперт С++
 Аватар для schdub
3073 / 1411 / 425
Регистрация: 19.01.2009
Сообщений: 3,894
15.10.2018, 23:14
poplan, начнем с самого очевидного:
Цитата Сообщение от poplan Посмотреть сообщение
C++
1
2
3
4
5
// ...
char *Res;
// ...
send(s2, Res, sizeof(Res) - 2, 0);
// ...
Т.к. Res - указатель на строку, то скорее всего вместо sizeof(Res) вы хотели strlen(Res) вызвать, а использование sizeof(Res) является ошибкой. Почему?
C++
1
2
3
4
5
6
7
    const char  Mas[] = "0123456789";
    const char* Res = Mas;
    std::cout << "sizeof(Res)=" << sizeof(Res) << std::endl; // sizeof(Res)=8 * для 64 бит,
                                                             // а на 32битной машине будет sizeof(Res)=4
                                                             // т.е. кол-во байт в указателе на вашей машине
    std::cout << "strlen(Res)=" << strlen(Res) << std::endl; // strlen(Res)=10 (строка без завершающаего нуля)
    std::cout << "sizeof(Mas)=" << sizeof(Mas) << std::endl; // sizeof(Mas)=11 (строка с завершающим нулем)
Цитата Сообщение от poplan Посмотреть сообщение
Res = new char[strlen(res) + 1];
то что выделено динамически должно быть удалено в конце текущего блока, а лучше использовать умные указатели, а еще лучше тут не использовать динамическое выделение. Зачем вам вообще понадобилось выделение дин памяти Res, вызов strcpy() если Res и res у вас содержат одно и то же значение?

Ну и к самому главному.

посылающая сторона
C++
1
2
3
4
5
// ...
char buf[255];
// ...
send(s, buf, sizeof(buf), 0);
// ...
принимающая сторона
C++
1
2
3
4
5
// ...
char b[255];
// ...
while (recv(s2, b, sizeof(b), 0) != 0) {
// ...
В этой схеме есть несколько проблем, но самая главная это то как вы читаете из сокета на принимающей стороне. В TCP нельзя так посылать большие блоки байт. Если на посылающей стороне вы отправляете 255 байт, то на принимающей стороне вы должный убедится, что прочли из сокета именно 255 байт и только после этого приступить к обработке принятого блока данных.

Первый вызов recv может получить любое кол-во байт от 0 до 255, допустим 10. 10 != 0 значит будет выполнятся тело while. У вас в буфере по индексам от 10 до 254 находится неинициализированный мусор, как уже отметил GbaLog-. Кое-как отроботало тело while и клиенту было послано значение в строке 38. Опять вызыватеся recv(), допустим в этот раз считывается уже 50 байт из оставшихся 255-10 байт (10 байт мы считали на предыдущей итерации). 50 != 0 и опять выполняется тело цикла while - сервер опять какую-то чушь шлет клиенту. И т.д.
1
1 / 1 / 0
Регистрация: 26.11.2017
Сообщений: 166
18.10.2018, 03:17  [ТС]
Да. Нужно модифицировать

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
#include "stdafx.h"
#include <winsock2.h>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#pragma comment(lib, "ws2_32.lib")
 
using namespace std;
 
int main() {
    WORD wVersionRequested;
    WSADATA wsaData;
    wVersionRequested = MAKEWORD(2, 2);
    WSAStartup(wVersionRequested, &wsaData);
    SOCKET s = socket(AF_INET, SOCK_STREAM, 0);
    struct sockaddr_in local;
    local.sin_family = AF_INET;
    local.sin_port = htons(1280);
    local.sin_addr.s_addr = htonl(INADDR_ANY);
    int c = bind(s, (struct sockaddr*)&local, sizeof(local));
    int r = listen(s, 5);
    while (true) {
        char buf[255], res[100], b[255], *Res;
        //структура определяет удаленный адрес, 
        //с которым  соединяется сокет 
        sockaddr_in remote_addr;
        int size = sizeof(remote_addr);
        SOCKET s2 = accept(s, (struct sockaddr*)&remote_addr, &size);
        while (recv(s2, b, sizeof(b), 0) != 0) {
            int i = 0;
            for (unsigned j = 3; j <= strlen(b); j += 4) {
                b[i] = '%';
                i++;
            }
            _itoa(i, res, 10);
            Res = new char[strlen(res) + 1];
            strcpy(Res, res);
            Res[strlen(res)] = '\0';
            //Посылает данные на соединенный сокет 
            send(s2, Res, sizeof(Res) - 2, 0);
        }
        closesocket(s2);
    }
    WSACleanup();
}
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
#include "stdafx.h"
#include <winsock2.h> 
#include <iostream> 
#include <stdio.h>
#include <stdlib.h> 
#pragma comment(lib, "ws2_32.lib")
 
using namespace std;
 
int main() {
    WORD wVersionRequested;
    WSADATA wsaData;
    wVersionRequested = MAKEWORD(2, 2);
    WSAStartup(wVersionRequested, &wsaData);
    struct sockaddr_in peer;
    peer.sin_family = AF_INET;
    peer.sin_port = htons(1280);
    //т.к.клиент и сервер на одном компьютере,
        //пишем адрес 127.0.0.119
        peer.sin_addr.s_addr = inet_addr("127.0.0.1");
    SOCKET s = socket(AF_INET, SOCK_STREAM, 0);
    connect(s, (struct sockaddr*) &peer, sizeof(peer));
    char buf[255], b[255];
    cout << "Enter the string, please" << endl;
    cin.getline(buf, 100, '\n');
    send(s, buf, sizeof(buf), 0);
    if (recv(s, b, sizeof(b), 0) != 0) {
        b[strlen(b)+1] = '\0'; 
        for (int i = 3; i < strlen(b); i += 4) {
            b[i] = '%';
        }
            cout << b << endl;
    }
    closesocket(s);
    WSACleanup();
    system("pause");
    return 0;
}
я тут потыкал и теперь он считает кол во четвертых символов

Добавлено через 1 час 37 минут
Я сделал. Спасибо
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
18.10.2018, 03:17
Помогаю со студенческими работами здесь

Клиент/сервер: клиент посылает серверу слово; определить, является ли это слово палиндромом
Осуществить взаимодействие клиента и сервера на основе протокола TCP/IP. Функционирование клиента и сервера реализовать следующим образом:...

Сервер ожидает recv, хотя клиент вроде посылает
добрый день, можете подсказать пожалуйста что может быть не так, вообщем у меня есть клиент и сервер и вроде все фурычит как мне нужно,...

Дана строка. Создайте приложение, преобразующее строку, удалив каждый символ «*» и повторив каждый символ, отличный от «*»
Дана строка. Создайте приложение, преобразующее строку, удалив каждый символ «*» и повторив каждый символ, отличный от «*».

Строка: Преобразовать строку, удалив каждый символ * и повторив каждый символ, отличный от *
Дана строка символов. Преобразовать строку, удалив каждый символ * и повторив каждый символ, отличный от *.

Преобразовать строку, удалив каждый символ <*> и повторив каждый символ отличный от <*>
Дана строка. Преобразовать её, удалив каждый символ &lt;*&gt; и повторив каждый символ отличный от &lt;*&gt;


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

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Новые блоги и статьи
YAFU@home — распределённые вычисления для математики. На CPU
Programma_Boinc 20.01.2026
YAFU@home — распределённые вычисления для математики. На CPU YAFU@home — это BOINC-проект, который занимается факторизацией больших чисел и исследованием aliquot-последовательностей. Звучит. . .
http://iceja.net/ математические сервисы
iceja 20.01.2026
Обновила свой сайт http:/ / iceja. net/ , приделала Fast Fourier Transform экстраполяцию сигналов. Однако предсказывает далеко не каждый сигнал (см ограничения http:/ / iceja. net/ fourier/ docs ). Также. . .
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь постоянного тока с R, L, C, k(ключ), U, E, J. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа, решает её и находит: токи, напряжения и их 1 и 2 производные при t = 0;. . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru