Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.97/37: Рейтинг темы: голосов - 37, средняя оценка - 4.97
 Аватар для xamelione25
-4 / 5 / 2
Регистрация: 04.02.2013
Сообщений: 1,861

Проблема с несовместимостью типов параметров char, const char, STRSAFE_LPWSTR, STRSAFE_LPCWSTR

06.07.2019, 13:35. Показов 9030. Ответов 80
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Проблемные вопросы отражены на скрине

Программа написана к заданию:
1. Разработать прикладной протокол для передачи файлов с помощью транспортного протокола TCP.
1.1. Разработать в Visual C++ приложение Windows для копирования файлов по протоколу, разработанному в п.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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
#include <winsock2.h>
#include <Windows.h>
#include <WindowsX.h>
#include <tchar.h>
#include <locale.h>
#include <CommCtrl.h>
#include <Strsafe.h>
#include <string.h>
#include <process.h>
#include <iostream>
#pragma comment ( lib, "ws2_32.lib" )
using namespace std;
#define SHUTDOWN(sock) if(sock != NULL) {shutdown(sock, SD_BOTH); closesocket(sock); sock = NULL;}
struct hostent* hst;
SRWLOCK SrwLock;
WSADATA wsaData;
SOCKET  s;
HANDLE hThread;
HWND hWnd;
HANDLE handleOfClients[20];
sockaddr_in SIN = { 0 };
#pragma pack(push,1)
struct Package
{
    const char recipients[4096];
    const char message[1024];
};
#pragma pack(pop)
TCHAR* host;
int nclients = 0;
Package msg;
SOCKET SocketClients[1024];
char* BaseNameClients[1024];
void GetClientNames(char string[]);
int WritePerSymbol(SOCKET s, char* buf, size_t length);
int ReadPerSymbol(SOCKET s, char* buf, size_t length);
 
unsigned int WINAPI ClientTread(LPVOID client_socket)
{
    SOCKET my_sock;
    my_sock = ((SOCKET*)client_socket)[0];
    const char* NameClients;
    for (;;)
    {
        int n = ReadPerSymbol(my_sock, (char*)& msg, sizeof(msg));
        if (n != SOCKET_ERROR)
        {
            if (strcmp(msg.recipients, "1") == 0)
            {
                int size = 0;
                for (int i = 0; i < nclients; ++i)
                {
                    size = size + strlen(BaseNameClients[i]) + 1;
                }
                NameClients = new char[size + 1];
                strcpy(NameClients, "");
                for (int i = 0; i < nclients; ++i)
                {
                    const char c = strlen(BaseNameClients[i]);
                    StringCchPrintf(NameClients, size + 1, "%s%c%s", NameClients, c, BaseNameClients[i]);
                }
                StringCchCopy(msg.message, 2, "");
                StringCchCopy(msg.recipients, const char(NameClients) + 1, NameClients);
                StringCchCat(msg.recipients, 1, '\0');
                WritePerSymbol(my_sock, (char*)& msg, sizeof(msg));
                delete[] NameClients;
            }
            else
            {
                GetClientNames(msg.recipients);
            }
            if (strcmp(msg.recipients, "0") == 0)
            {
                break;
            }
        }
        else break;
    }
    int currentNameLen = 0;
    getsockname(my_sock, NULL, &currentNameLen);
    char* CurrentName = new char[currentNameLen + 1];
    int err = getsockname(my_sock, (sockaddr*)CurrentName, &currentNameLen);
    if (err != SOCKET_ERROR)
    {
        AcquireSRWLockExclusive(&SrwLock);
        for (int i = 0; i < nclients; ++i)
        {
            if (strcpy(CurrentName, BaseNameClients[i]) == 0)
            {
                CloseHandle(handleOfClients[i]);
                for (int j = i; j < nclients; ++j)
                {
                    BaseNameClients[j] = BaseNameClients[j + 1];
                    SocketClients[j] = SocketClients[j + 1];
                    handleOfClients[j] = handleOfClients[j + 1];
                }
            }
        }
        ReleaseSRWLockShared(&SrwLock);
    }
    delete[]BaseNameClients[nclients];
    nclients--;
    printf("-отключен\n");
    SHUTDOWN(my_sock);
    return 0;
}
 
int _tmain()
{
    setlocale(LC_ALL, "Russian");
    int err = WSAStartup(MAKEWORD(2, 2), &wsaData);
    s = socket(AF_INET, SOCK_STREAM, 0);
    if (s == INVALID_SOCKET)
    {
        printf("Socket error: %d\n", WSAGetLastError());
        WSACleanup();
    }
    SIN.sin_family = AF_INET;
    SIN.sin_port = htons(5150);
    SIN.sin_addr.s_addr = INADDR_ANY;
 
    err = bind(s, (sockaddr*)& SIN, sizeof(SIN));
 
    if (SOCKET_ERROR != err)
    {
        err = listen(s, 5);
    }
 
    if (SOCKET_ERROR != err)
    {
        for (;;)
        {
            sockaddr_in client_addr;
            int client_addr_size = sizeof(client_addr);
            SOCKET client_socket = accept(s, (sockaddr*)& client_addr, &client_addr_size);
            if (INVALID_SOCKET == client_socket)
            {
                nclients++;
                if (WSAEINTR == WSAGetLastError()) break;
            }
            else
            {
                SocketClients[nclients] = client_socket;
                hst = gethostbyaddr((char*)& client_addr.sin_addr.s_addr, 4, AF_INET);
                printf("+%s [%s] был подключен\n",
                    (hst) ? hst->h_name : "", inet_ntoa(client_addr.sin_addr));
                BaseNameClients[nclients] = new char[strlen(hst->h_name)];
                strcpy(BaseNameClients[nclients], hst->h_name);
                //strcat(BaseNameClients[nclients], "%");
                nclients++;
                InitializeSRWLock(&SrwLock);
                handleOfClients[nclients] = (HANDLE)_beginthreadex(NULL, NULL, ClientTread, &client_socket, NULL, NULL);
            }
        }
        WaitForMultipleObjects(nclients, handleOfClients, TRUE, INFINITE);
        SHUTDOWN(s);
    }
}
 
int ReadPerSymbol(SOCKET s, char* buf, size_t length)
{
    int all = length;
    int received = 0;
    while (all > 0)
    {
        received = recv(s, buf, all, 0);
        if (received < 0) return SOCKET_ERROR;
        buf += received;
        all -= received;
    }
    return length;
}
 
int WritePerSymbol(SOCKET s, char* buf, size_t length)
{
    int all = length;
    int sended = 0;
    while (all > 0)
    {
        sended = send(s, buf, all, 0);
        if (sended < 0) return SOCKET_ERROR;
        buf += sended;
        all -= sended;
    }
    return length;
}
 
void GetClientNames(char string[])
{
    unsigned int i = 0;
    unsigned int numOfClients = 0;
    do
    {
        int n = string[i];
        char* clientName = new char[n + 1];
        for (int k = 0; k < n; k++)
        {
            clientName[k] = string[i + 1 + k];
        }
        clientName[n] = '\0';
        cout << clientName << endl;
        strcat(clientName, "%");
        for (int j = 0; j < nclients; ++j)
        {
            if (strcmp(clientName, BaseNameClients[j]) == 0)
            {
                int n = WritePerSymbol(SocketClients[j], (char*)& msg, sizeof(msg));
            }
        }
        numOfClients++;
        delete[]clientName;
        i += n + 1;
    } while (i < 4096 || string[i] != '\0');
    cout << numOfClients << endl;
}
Миниатюры
Проблема с несовместимостью типов параметров char, const char, STRSAFE_LPWSTR, STRSAFE_LPCWSTR  
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
06.07.2019, 13:35
Ответы с готовыми решениями:

CONST_RETURN char *__cdecl strstr (const char *_Str, const char *_SubStr)
#include &lt;stdio.h&gt; #include &lt;string.h&gt; char tracks = { &quot;ya ostavil svoe serdce v harvardskom med univere&quot;, &quot;NewYork New York...

error: no matching function for call to `QObject::connect(QPushButton&, const char[10], QApplication*, const char[8])'
Ошибка понимаю какая, но не понимаю, почему возникла и как исправить!) #include &lt;QtGui&gt; int main(int argc, char *argv) { ...

no matching function for call to 'QObject::connect(QCommandLinkButton*, const char*, cNetwork*, const char*)
компилятор ругается ошибка: no matching function for call to 'QObject::connect(QCommandLinkButton*, const char*, cNetwork*, const char*)'...

80
19506 / 10109 / 2464
Регистрация: 30.01.2014
Сообщений: 17,834
07.07.2019, 23:35
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от xamelione25 Посмотреть сообщение
почему очень большое???
Вы же понимаете, что я вашу программу отладить не могу, в отличие от вас. Вот возьмите и посмотрите почему
Например вы можете посмотреть чем численно равно n при возникновении исключения. Если оно отрицательное, значит я прав.
Если это подтвердится, значит вам нужно будет внимательно смотреть как формируется string.

Добавлено через 3 минуты
Вообще в вашей программе много непонятного.
А какого вообще черта значения string[i] используются как размерность массива? В string[i] лежат не символы, а размеры? А почему оно тогда называется string - строка?
0
 Аватар для xamelione25
-4 / 5 / 2
Регистрация: 04.02.2013
Сообщений: 1,861
07.07.2019, 23:38  [ТС]
DrOffset, Я делаю все по аналогии из выданного мне примера который выполнялся на VS2010. и пытаясь запустить его на VS2019 я напоролся впоследсвии на много несостыковок и несоответствий
0
 Аватар для xamelione25
-4 / 5 / 2
Регистрация: 04.02.2013
Сообщений: 1,861
07.07.2019, 23:48  [ТС]
Цитата Сообщение от DrOffset Посмотреть сообщение
Если оно отрицательное, значит я прав.
Вероятно да
Миниатюры
Проблема с несовместимостью типов параметров char, const char, STRSAFE_LPWSTR, STRSAFE_LPCWSTR  
0
19506 / 10109 / 2464
Регистрация: 30.01.2014
Сообщений: 17,834
07.07.2019, 23:52
xamelione25, ну наверное надо все-таки понимать что и зачем делается.
Допустим, что размеры - это правильно (там выше есть код, который формирует строку с размером между символьными данными). Но вот вы можете объяснить что этот код по вашей задумке должен делать?
Цитата Сообщение от xamelione25 Посмотреть сообщение
C++
1
StringCchCopy(msg.recipients, const char(NameClients) + 1, NameClients);
Зачем вы указатель приводите к char?
0
 Аватар для xamelione25
-4 / 5 / 2
Регистрация: 04.02.2013
Сообщений: 1,861
07.07.2019, 23:58  [ТС]
DrOffset,
Цитата Сообщение от DrOffset Посмотреть сообщение
Зачем вы указатель приводите к char?
Вы не на тот код смотрите.....я вам скинул код с последним форматированием в 56м посте этой темы
0
19506 / 10109 / 2464
Регистрация: 30.01.2014
Сообщений: 17,834
08.07.2019, 00:41
Цитата Сообщение от xamelione25 Посмотреть сообщение
Вы не на тот код смотрите.....я вам скинул код с последним форматированием в 56м посте этой темы
Действительно.
Ладно. Тогда вопрос такой, вот код:
C++
1
StringCchPrintf(NameClients, size + 1, "%s%c%s", NameClients, c, BaseNameClients[i]);
Мне кажется он некорректный. Буфер чтения и буфер записи совпадают.

Попробуйте этот кусок переписать так:
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
...........
        int n = ReadPerSymbol(my_sock, (char*)& msg, sizeof(msg));
        if (n != SOCKET_ERROR)
        {
            if (strcmp(msg.recipients, "1") == 0)
            {
                char * NameClients = msg.recipients;
                size_t off = 0;
                for (int i = 0; i < nclients; ++i)
                {
                    size_t c = strlen(BaseNameClients[i]);
 
                    NameClients[off] = c;
                    strncpy(&NameClients[off + 1], BaseNameClients[i], c);
 
                    off += c + 1;
                }
                NameClients[off] = 0;
                StringCchCopy(msg.message, 2, "");
                WritePerSymbol(my_sock, (char*)& msg, sizeof(msg));
            }
            else
            {
                GetClientNames(msg.recipients);
            }
            if (strcmp(msg.recipients, "0") == 0)
            {
                break;
            }
        }
        else break;
.........
Может это и не поможет (я не проверял, писал прямо в браузере), но точно будет быстрее, чем было и одним подозрительным местом меньше.
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
08.07.2019, 09:16
Цитата Сообщение от xamelione25 Посмотреть сообщение
Ну я забил в отправку сообщение "12" ... почему очень большое??? Или может он просто все отправляемое он не правильно идентифицирует???
Посмотри в отладчике, что у мебя пришло в msg, после ReadPerSymbol
0
 Аватар для xamelione25
-4 / 5 / 2
Регистрация: 04.02.2013
Сообщений: 1,861
20.07.2019, 01:30  [ТС]
oleg-m1973, а это может о чем-то сказать?. Это сразу же после отправки сообщения при пошаговом запуске
Миниатюры
Проблема с несовместимостью типов параметров char, const char, STRSAFE_LPWSTR, STRSAFE_LPCWSTR  
0
19506 / 10109 / 2464
Регистрация: 30.01.2014
Сообщений: 17,834
20.07.2019, 01:32
xamelione25, а с кодом, который я предложил выше, ваша проблема не решилась?
0
 Аватар для xamelione25
-4 / 5 / 2
Регистрация: 04.02.2013
Сообщений: 1,861
20.07.2019, 01:36  [ТС]
DrOffset, это с вашими уже....
Миниатюры
Проблема с несовместимостью типов параметров char, const char, STRSAFE_LPWSTR, STRSAFE_LPCWSTR  
0
 Аватар для xamelione25
-4 / 5 / 2
Регистрация: 04.02.2013
Сообщений: 1,861
20.07.2019, 01:40  [ТС]
DrOffset,
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
#define _CRT_SECURE_NO_WARNINGS 1
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <winsock2.h>
#include <Windows.h>
#include <WindowsX.h>
#include <tchar.h>
#include <locale.h>
#include <CommCtrl.h>
#include <Strsafe.h>
#include <string.h>
#include <process.h>
#include <iostream>
#pragma comment ( lib, "ws2_32.lib" )
using namespace std;
#define SHUTDOWN(sock) if(sock != NULL) {shutdown(sock, SD_BOTH); closesocket(sock); sock = NULL;}
struct hostent* hst;
SRWLOCK SrwLock;
WSADATA wsaData;
SOCKET  s;
HANDLE hThread;
HWND hWnd;
HANDLE handleOfClients[20];
sockaddr_in SIN = { 0 };
#pragma pack(push,1)
struct Package
{
    char recipients[4096];
    char message[1024];
};
#pragma pack(pop)
TCHAR* host;
int nclients = 0;
Package msg;
SOCKET SocketClients[1024];
char* BaseNameClients[1024];
void GetClientNames(char string[]);
int WritePerSymbol(SOCKET s, char* buf, size_t length);
int ReadPerSymbol(SOCKET s, char* buf, size_t length);
 
unsigned int WINAPI ClientTread(LPVOID client_socket)
{
    SOCKET my_sock;
    my_sock = ((SOCKET*)client_socket)[0];
    char* NameClients;
    for (;;)
    {
        int n = ReadPerSymbol(my_sock, (char*)& msg, sizeof(msg));
        if (n != SOCKET_ERROR)
        {
            if (strcmp(msg.recipients, "1") == 0)
            {
                char* NameClients = msg.recipients;
                size_t off = 0;
                for (int i = 0; i < nclients; ++i)
                {
                    size_t c = strlen(BaseNameClients[i]);
 
                    NameClients[off] = c;
                    strncpy(&NameClients[off + 1], BaseNameClients[i], c);
 
                    off += c + 1;
                }
                NameClients[off] = 0;
                StringCchCopy(msg.message, 2, "");
                WritePerSymbol(my_sock, (char*)& msg, sizeof(msg));
            }
            else
            {
                GetClientNames(msg.recipients);
            }
            if (strcmp(msg.recipients, "0") == 0)
            {
                break;
            }
        }
        else break;
    }
    int currentNameLen = 0;
    getsockname(my_sock, NULL, &currentNameLen);
    char* CurrentName = new char[currentNameLen + 1];
    int err = getsockname(my_sock, (sockaddr*)CurrentName, &currentNameLen);
    if (err != SOCKET_ERROR)
    {
        AcquireSRWLockExclusive(&SrwLock);
        for (int i = 0; i < nclients; ++i)
        {
            if (strcpy(CurrentName, BaseNameClients[i]) == 0)
            {
                CloseHandle(handleOfClients[i]);
                for (int j = i; j < nclients; ++j)
                {
                    BaseNameClients[j] = BaseNameClients[j + 1];
                    SocketClients[j] = SocketClients[j + 1];
                    handleOfClients[j] = handleOfClients[j + 1];
                }
            }
        }
        ReleaseSRWLockShared(&SrwLock);
    }
    delete[]BaseNameClients[nclients];
    nclients--;
    printf("-отключен\n");
    SHUTDOWN(my_sock);
    return 0;
}
 
int _tmain()
{
    setlocale(LC_ALL, "Russian");
    int err = WSAStartup(MAKEWORD(2, 2), &wsaData);
    s = socket(AF_INET, SOCK_STREAM, 0);
    if (s == INVALID_SOCKET)
    {
        printf("Socket error: %d\n", WSAGetLastError());
        WSACleanup();
    }
    SIN.sin_family = AF_INET;
    SIN.sin_port = htons(5150);
    SIN.sin_addr.s_addr = INADDR_ANY;
 
    err = bind(s, (sockaddr*)& SIN, sizeof(SIN));
 
    if (SOCKET_ERROR != err)
    {
        err = listen(s, 5);
    }
 
    if (SOCKET_ERROR != err)
    {
        for (;;)
        {
            sockaddr_in client_addr;
            int client_addr_size = sizeof(client_addr);
            SOCKET client_socket = accept(s, (sockaddr*)& client_addr, &client_addr_size);
            if (INVALID_SOCKET == client_socket)
            {
                nclients++;
                if (WSAEINTR == WSAGetLastError()) break;
            }
            else
            {
                SocketClients[nclients] = client_socket;
                hst = gethostbyaddr((char*)& client_addr.sin_addr.s_addr, 4, AF_INET);
                printf("+%s [%s] был подключен\n", (hst) ? hst->h_name : "", inet_ntoa(client_addr.sin_addr));
                BaseNameClients[nclients] = new char[strlen(hst->h_name)];
                strcpy(BaseNameClients[nclients], hst->h_name);
                //strcat(BaseNameClients[nclients], "%");
                nclients++;
                InitializeSRWLock(&SrwLock);
                handleOfClients[nclients] = (HANDLE)_beginthreadex(NULL, NULL, ClientTread, &client_socket, NULL, NULL);
            }
        }
        WaitForMultipleObjects(nclients, handleOfClients, TRUE, INFINITE);
        SHUTDOWN(s);
    }
}
 
int ReadPerSymbol(SOCKET s, char* buf, size_t length)
{
    int all = length;
    int received = 0;
    while (all > 0)
    {
        received = recv(s, buf, all, 0);
        if (received < 0) return SOCKET_ERROR;
        buf += received;
        all -= received;
    }
    return length;
}
 
int WritePerSymbol(SOCKET s, char* buf, size_t length)
{
    int all = length;
    int sended = 0;
    while (all > 0)
    {
        sended = send(s, buf, all, 0);
        if (sended < 0) return SOCKET_ERROR;
        buf += sended;
        all -= sended;
    }
    return length;
}
 
void GetClientNames(char string[])
{
    unsigned int i = 0;
    unsigned int numOfClients = 0;
    do
    {
        int n = string[i];
        char* clientName = new char[n + 2];
        for (int k = 0; k < n; k++)
        {
            clientName[k] = string[i + 10 + k];
        }
        clientName[n] = '\0';
        cout << clientName << endl;
        strcat(clientName, "%");
        for (int j = 0; j < nclients; ++j)
        {
            if (strcmp(clientName, BaseNameClients[j]) == 0)
            {
                int n = WritePerSymbol(SocketClients[j], (char*)& msg, sizeof(msg));
            }
        }
        numOfClients++;
        delete[]clientName;
        i += n + 2;
    } while (i < 4096 || string[i] != '\0');
    cout << numOfClients << endl;
}
Добавлено через 2 минуты
DrOffset, oleg-m1973,
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Посмотри в отладчике, что у мебя пришло вmsg, после ReadPerSymbol
Не понятно то, что он в этот сектор вообще не заходит при пошаговом запуске
0
19506 / 10109 / 2464
Регистрация: 30.01.2014
Сообщений: 17,834
20.07.2019, 01:45
xamelione25, а клиента к вашему серверу выложите? тогда можно будет полноценно потестировать и не искать ошибку глазами на форуме, а запустить отладчик.
0
 Аватар для xamelione25
-4 / 5 / 2
Регистрация: 04.02.2013
Сообщений: 1,861
20.07.2019, 01:46  [ТС]
DrOffset,
Кликните здесь для просмотра всего текста
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
#define _CRT_SECURE_NO_WARNINGS 1
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <winsock2.h>
#include <Windows.h>
#include <WindowsX.h>
#include <tchar.h>
#include <locale.h>
#include <CommCtrl.h>
#include <Strsafe.h>
#include <string.h>
#include <process.h>
#include <math.h> 
#include <iostream>
#include <string>
#pragma comment (lib, "ws2_32.lib")
using namespace std;
#define SERVER "192.168.0.105"
#define IDC_STATIC_MESSAGE 2001
#define IDC_EDIT_MESSAGE 2002
#define IDC_LISTBOX 2003
#define IDC_BUTTON_SEND 2004
#define IDC_BUTTON_UPDATE 2005
#define IDC_LISTB2 2006
#define IDC_STATIC_DIALOG 2007
#define IDC_COMBOBOX 2008
#define IDC_BUTTON_ADD 2009
#define IDC_BUTTON_CLEAR 2010
#define SHUTDOWN(sock) if(sock != NULL) {shutdown(sock, SD_BOTH); closesocket(sock); sock = NULL;}
struct hostent* hst;
sockaddr_in SIN = {0};
#pragma pack(push,1)
struct Package
{
    CHAR recipients[4096];
    CHAR message[1024];
};
#pragma pack(pop)
LRESULT CALLBACK windowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lparam);
BOOL OnCreate(HWND hwnd, LPCREATESTRUCT lpCreateStruct);
void OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify);
void OnDestroy(HWND hwnd);
void GetClientNames(char string[], HWND hwndLB);
int WritePerSymbol(SOCKET s, char* buf, size_t length);
int ReadPerSymbol(SOCKET s, char* buf, size_t length);
void ButtonSend(HWND hwnd);
void ButtonUpdate(HWND hwnd);
void ButtonAdd(HWND hwnd);
void ButtonClearLB(HWND hwnd);
HWND hDlg = NULL;
BOOL PreTranslateMessage(LPMSG lpMsg);
WSADATA wsaData;
SOCKET s;
HANDLE hThread;
HWND hWnd;
char host[50];
unsigned int CALLBACK ThreadFunc(LPVOID lpParameter);
int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE, LPTSTR lpszCmdLine, int nCmdShow)
{
    setlocale(LC_ALL, "Russian");
    WNDCLASSEX wcex = { sizeof(WNDCLASSEX) };
    wcex.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
    wcex.lpfnWndProc = windowProc; // оконная процедура
    wcex.hInstance = hInstance;
    wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
    wcex.lpszMenuName = NULL;
    wcex.lpszClassName = TEXT("winClass"); // имя класса
    wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
    if (0 == RegisterClassEx(&wcex))
        return -1;
    LoadLibrary(TEXT("ComCtl32.dll"));
    hWnd = CreateWindowEx(0, TEXT("winClass"), TEXT("Labaratornaya4"), WS_OVERLAPPEDWINDOW & (~WS_MAXIMIZEBOX)^WS_THICKFRAME, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
    if (NULL == hWnd)
        return -1;
    ShowWindow(hWnd, nCmdShow);
    MSG msg;
    BOOL bRet;
    for (;;)
    {
        // определяем наличие сообщений в очереди
        while (!PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
        {
        } // while
        // извлекаем сообщение из очереди
        bRet = GetMessage(&msg, NULL, 0, 0);
        if (bRet == -1)
        {
            /* обработка ошибки и возможно выход из цикла */
        } // if
        else if (FALSE == bRet)
        {
            break; // получено WM_QUIT, выход из цикла
        } // if
        else if (PreTranslateMessage(&msg) == FALSE)
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        } // if
    } // for
    return (int)msg.wParam; // завершаем работу приложения
} // _tWinMain
LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
        HANDLE_MSG(hWnd, WM_CREATE, OnCreate);
        HANDLE_MSG(hWnd, WM_DESTROY, OnDestroy);
        HANDLE_MSG(hWnd, WM_COMMAND, OnCommand);
    }
    return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
BOOL PreTranslateMessage(LPMSG lpMsg)
{
    return IsDialogMessage(hDlg, lpMsg);
} // PreTranslateMessage
BOOL OnCreate(HWND hwnd, LPCREATESTRUCT lpCreateStruct)
{
    if (NULL != hwnd)
    {
        CreateWindowEx(0, TEXT("Static"), TEXT("Сообщение:"), ES_AUTOHSCROLL | ES_LEFT | WS_CHILD | WS_VISIBLE, 250, 90, 225, 25, hwnd, (HMENU)IDC_STATIC_MESSAGE, lpCreateStruct->hInstance, NULL);
        CreateWindowExA(0, "Edit", "", WS_CHILD | WS_VISIBLE | WS_BORDER, 250, 120, 620, 25, hwnd, (HMENU)IDC_EDIT_MESSAGE, lpCreateStruct->hInstance, NULL);
        CreateWindowEx(0, TEXT("Button"), TEXT("отправить"), WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 250, 160, 620, 25, hwnd, (HMENU)IDC_BUTTON_SEND, lpCreateStruct->hInstance, NULL);
        CreateWindowEx(0, TEXT("Button"), TEXT("обновить"), WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 360, 10, 100, 25, hwnd, (HMENU)IDC_BUTTON_UPDATE, lpCreateStruct->hInstance, NULL);
        CreateWindowEx(0, TEXT("Button"), TEXT("добавить"), WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 250, 10, 100, 25, hwnd, (HMENU)IDC_BUTTON_ADD, lpCreateStruct->hInstance, NULL);
        CreateWindowEx(0, TEXT("Button"), TEXT("очистить контакты"), WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 250, 40, 210, 25, hwnd, (HMENU)IDC_BUTTON_CLEAR, lpCreateStruct->hInstance, NULL);
        CreateWindowEx(0, TEXT("Static"), TEXT("Диалог:"), ES_AUTOHSCROLL | ES_LEFT | WS_CHILD | WS_VISIBLE, 20, 210, 225, 25, hwnd, (HMENU)IDC_STATIC_DIALOG, lpCreateStruct->hInstance, NULL);
        CreateWindowEx(0, TEXT("ListBox"), NULL, WS_CHILD | WS_VISIBLE | WS_BORDER | WS_HSCROLL, 20, 240, 850, 210, hwnd, (HMENU)IDC_LISTBOX, lpCreateStruct->hInstance, NULL);
        CreateWindowEx(0, TEXT("ComboBox"), NULL, WS_CHILD | WS_VISIBLE | CBS_SORT | CBS_DROPDOWNLIST, 20, 10, 220, 400, hwnd, (HMENU)IDC_COMBOBOX, lpCreateStruct->hInstance, NULL);
        CreateWindowExA(0, "ListBox", NULL, WS_CHILD | WS_VISIBLE | WS_BORDER | WS_HSCROLL | WS_VSCROLL | LBS_MULTIPLESEL, 20, 40, 220, 150, hwnd, (HMENU)IDC_LISTB2, lpCreateStruct->hInstance, NULL);
        int err = WSAStartup(MAKEWORD(2, 2), &wsaData);
        if (0 == err)
        {/* Инициализация WinSock выполнена успешно */
        } // if
        s = socket(AF_INET, SOCK_STREAM, 0);
        if (s == INVALID_SOCKET)
        {
            printf("Socket error: %d\n", WSAGetLastError());
            WSACleanup();
        }
        SIN.sin_family = AF_INET; // семейство адресов = IPv4
        SIN.sin_port = htons(5150);
        SIN.sin_addr.s_addr = inet_addr(SERVER);
        if (SOCKET_ERROR != err)
        {
            err = connect(s, (sockaddr*)& SIN, sizeof(SIN));
            /* Сокет успешно ассоциирован */
            if (SOCKET_ERROR == err)
            {
                const auto e = ::WSAGetLastError();
                ::MessageBox(hwnd, std::to_string(e).c_str(), "ERROR!!!", MB_OK);
                MessageBox(hwnd, TEXT("Ошибка! Не удалось установить соединение"), TEXT("Установка соеденения с сервером"), MB_OK | MB_ICONERROR);
            }
            hThread = (HANDLE)_beginthreadex(NULL, NULL, ThreadFunc, NULL, NULL, NULL);
        } // if
    } // if
    DWORD cchSize = 50;
    GetComputerNameEx(ComputerNamePhysicalDnsHostname, host, &cchSize);
    return TRUE;
}
void OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
{
    if (BN_CLICKED == codeNotify)
    {
        HINSTANCE hInstance = GetWindowInstance(hwnd);
        switch (id)
        {
        case IDC_BUTTON_SEND:
        {ButtonSend(hwnd);}
        break;
        case IDC_BUTTON_UPDATE:
        {ButtonUpdate(hwnd);}
        break;
        case IDC_BUTTON_ADD:
        {ButtonAdd(hwnd);}
        break;
        case IDC_BUTTON_CLEAR:
        {ButtonClearLB(hwnd);}
        break;
        }
    }//if
}
void OnDestroy(HWND hwnd)
{
    Package msg;
    StringCchCopyA(msg.recipients, 2, "0");
    WritePerSymbol(s, (char*)& msg, sizeof(msg));
    SHUTDOWN(s);
    WaitForSingleObject(hThread, INFINITE);
    CloseHandle(hThread);
    PostQuitMessage(0); // отправляем сообщение WM_QUIT
}
unsigned int CALLBACK ThreadFunc(LPVOID lpParameter)
{
    Package msg;
    for (;;)
    {
        // получаем текстовое сообщение
        int   n = ReadPerSymbol(s, (char*)& msg, sizeof(msg));
        if (SOCKET_ERROR != n) // сообщение успешно получено
        {
            if (strcmp(msg.message, "") == 0)
            {
                HWND hwndCB = GetDlgItem(hWnd, IDC_COMBOBOX);
                GetClientNames(msg.recipients, hwndCB);
            }
            else
            {
                HWND hwndLB = GetDlgItem(hWnd, IDC_LISTBOX);
                SendMessageA(hwndLB, LB_ADDSTRING, NULL, (LPARAM)msg.message);
            }
        } // if 
        else
            if (WSAEINTR == WSAGetLastError()) break;
    }
    return 0;
}
void GetClientNames(char string[], HWND hwndCB)
{
    ComboBox_ResetContent(hwndCB);
    int j = 0;
    unsigned int i = 0;
    do
    {
        int n = string[i];
        char* clientName = new char[n + 1];
        for (int k = 0; k < n; k++)
        {
            clientName[k] = string[i + 1 + k];
        }
        clientName[n] = '\0';
        ComboBox_AddString(hwndCB, clientName);
        delete[]clientName;
        i += n + 1;
    } while (i < 4096 && string[i] != '\0');
    ComboBox_SetCurSel(hwndCB, 0);
}
int ReadPerSymbol(SOCKET s, char* buf, size_t length)
{
    int all = length;
    int received = 0;
    while (all > 0)
    {
        received = recv(s, buf, all, 0);
        if (received < 0) return SOCKET_ERROR;
        buf += received;
        all -= received;
    }
    return length;
}
int WritePerSymbol(SOCKET s, char* buf, size_t length)
{
    int all = length;
    int sended = 0;
    while (all > 0)
    {
        sended = send(s, buf, all, 0);
        if (sended < 0) return SOCKET_ERROR;
        buf += sended;
        all -= sended;
    }
    return length;
}
void ButtonSend(HWND hwnd)
{
    Package msg;
    HWND hwndEdit = GetDlgItem(hwnd, IDC_EDIT_MESSAGE);
    HWND hwndLB = GetDlgItem(hWnd, IDC_LISTB2);
    int sizeText = Edit_GetTextLength(hwndEdit);
    GetDlgItemTextA(hwnd, IDC_EDIT_MESSAGE, msg.message, sizeText + 1);
    char Buff[1024];
    StringCchPrintf(Buff, 1024, "%s", msg.message);
    StringCchPrintf(msg.message, 1024, "[%s]: %s", host, Buff);
    int cItems = ListBox_GetCount(hwndLB);
    int* indexes = new int[cItems];
    int numOfSelected = ListBox_GetSelItems(hwndLB, cItems, indexes);
    int size = 0;
    strcpy(msg.recipients, "");
    for (int i = 0; i < cItems; ++i)
    {
        ListBox_GetText(hwndLB, indexes[i], Buff);
        char c = strlen(Buff);
        StringCchPrintf(msg.recipients, 4096, "%s%c%s", msg.recipients, c, Buff);
    }
    WritePerSymbol(s, (char*)& msg, sizeof(msg));
    SetDlgItemTextA(hwnd, IDC_EDIT_MESSAGE, "");
}
void ButtonUpdate(HWND hwnd)
{
    Package msg;
    StringCchCopyA(msg.recipients, 2, "1");
    WritePerSymbol(s, (char*)& msg, sizeof(msg));
}
void ButtonAdd(HWND hwnd)
{
    HWND hwndCB = GetDlgItem(hwnd, IDC_COMBOBOX);
    HWND hwndLB = GetDlgItem(hwnd, IDC_LISTB2);
    char buf[MAX_PATH];
    int ind = ComboBox_GetCurSel(hwndCB);
    SendMessage(hwndCB, CB_GETLBTEXT, ind, (LPARAM)buf);
    SendMessageA(hwndLB, LB_ADDSTRING, NULL, (LPARAM)buf);
}
void ButtonClearLB(HWND hwnd)
{
    HWND hwndLB = GetDlgItem(hwnd, IDC_LISTB2);
    ListBox_ResetContent(hwndLB);
}
0
 Аватар для xamelione25
-4 / 5 / 2
Регистрация: 04.02.2013
Сообщений: 1,861
20.07.2019, 01:49  [ТС]
DrOffset,
Вложения
Тип файла: rar repos.rar (1.67 Мб, 3 просмотров)
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
20.07.2019, 10:28
Цитата Сообщение от xamelione25 Посмотреть сообщение
Не понятно то, что он в этот сектор вообще не заходит при пошаговом запуске
В твоей ThreadFunc, прежде чем вызывать ReadPerSymbol надо ждать, что данные пришли, при помощи select или WSAPoll.
Ну и, у тебя точно клиент всегда посылает 5 килобайт данных, которые ты пытаешься получить в ReadPerSymbol?
0
 Аватар для xamelione25
-4 / 5 / 2
Регистрация: 04.02.2013
Сообщений: 1,861
20.07.2019, 17:02  [ТС]
DrOffset, у тебя запускается все нормально из 74го поста???
0
20.07.2019, 17:04

Не по теме:

xamelione25, я посмотрю, но попозже. Пока не было времени.

0
 Аватар для xamelione25
-4 / 5 / 2
Регистрация: 04.02.2013
Сообщений: 1,861
27.07.2019, 16:35  [ТС]
DrOffset,
Цитата Сообщение от DrOffset Посмотреть сообщение
я посмотрю, но попозже. Пока не было времени.
Не смотрел?
0
19506 / 10109 / 2464
Регистрация: 30.01.2014
Сообщений: 17,834
27.07.2019, 17:42
Цитата Сообщение от xamelione25 Посмотреть сообщение
Не смотрел?
Я смотрел и даже начал что-то исправлять, но потом оставил - т.к. это начало превращаться в переписывания всего задания за вас. Тут надо все переделывать.

У вас должен быть одинаковый код для приема и отправки на два ваших проекта, клиента и сервера. Не надо повторять одно и тоже - это чревато ошибками.

Нарисуйте на бумажке протокол, где и какие данные должны располагаться.
Создайте структуры для этого протокола.
Проверьте сначала без сети, что все данные попадают на свои места и что их можно прочитать. Можете для примера записывать структуру в файл, потом пытаться ее считать.

Затем отдельно напишите функции сетевой передачи и приема. Оттестируйте их на простых данных, чтобы, грубо говоря, массив данных нужного размера нормально отсылался и принимался. Используйте для этого простой подход: сначала размер блока, затем остальной блок. Помните, что данные при сетевом взаимодействии не обязаны приходить теми же порциями, что были отправлены.

Когда добъетесь стабильной отправки и приема массивов, то прикручивайте реализацию протокола.

Только потом делайте пользовательский интерфейс.

Найдите книгу "UNIX: Разработка сетевых приложений", она вам поможет в деталях.
0
 Аватар для xamelione25
-4 / 5 / 2
Регистрация: 04.02.2013
Сообщений: 1,861
27.07.2019, 23:21  [ТС]
DrOffset, подскажи а что в этом коде не правильно???


Кликните здесь для просмотра всего текста
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
#pragma comment(lib, "ws2_32.lib")
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
int __cdecl main(void)
{
    WSADATA wsaData;
    SOCKET ListenSocket, ClientSocket;  // впускающий сокет и сокет для клиентов
    sockaddr_in ServerAddr;  // это будет адрес сервера
    int err, maxlen = 512;  // код ошибки и размер буферов
    char* recvbuf = new char[maxlen];  // буфер приема
    char* result_string = new char[maxlen];  // буфер отправки
    // Initialize Winsock
    WSAStartup(MAKEWORD(2, 2), &wsaData);
    // Create a SOCKET for connecting to server
    ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    // Setup the TCP listening socket
    ServerAddr.sin_family = AF_INET;
    ServerAddr.sin_addr.s_addr = inet_addr("192.168.0.105");
    ServerAddr.sin_port = htons(12345);
    err = bind(ListenSocket, (sockaddr*)& ServerAddr, sizeof(ServerAddr));
    if (err == SOCKET_ERROR) {
        printf("bind failed: %d\n", WSAGetLastError());
        closesocket(ListenSocket);
        WSACleanup();
        return 1;
    }
 
    err = listen(ListenSocket, 50);
    if (err == SOCKET_ERROR) {
        printf("listen failed: %d\n", WSAGetLastError());
        closesocket(ListenSocket);
        WSACleanup();
        return 1;
    }
    while (true) {
        // Accept a client socket
        ClientSocket = accept(ListenSocket, NULL, NULL);
        err = recv(ClientSocket, recvbuf, maxlen, 0);
        if (err > 0) {
            recvbuf[err] = 0;
            printf("Received query: %s\n", (char*)recvbuf);
            // вычисляем результат
            int result = 72;
            _snprintf_s(result_string, maxlen, maxlen, "OK %d\n", result);
            // отправляем результат на сервер
            send(ClientSocket, result_string, strlen(result_string), 0);
            printf("Sent answer: %s\n", result_string);
        }
        else if (err == 0)
            printf("Connection closing...\n");
        else {
            printf("recv failed: %d\n", WSAGetLastError());
            closesocket(ClientSocket);
            WSACleanup();
            return 1;
        }
 
        // shutdown the connection since we're done
        closesocket(ClientSocket);
    }
}


Я нашел это на сайте
http://it.mmcs.sfedu.ru/wiki/В... ммирование

Увидел недочет в коде - исправил аналогично тому как ты писал когда-то в теме.
'inet_addr': Use inet_pton() or InetPton()

но ничего почему-то не изменилось...что-то видимо неправильно сделал


Исправил в настройках - см.скрины
Миниатюры
Проблема с несовместимостью типов параметров char, const char, STRSAFE_LPWSTR, STRSAFE_LPCWSTR   Проблема с несовместимостью типов параметров char, const char, STRSAFE_LPWSTR, STRSAFE_LPCWSTR   Проблема с несовместимостью типов параметров char, const char, STRSAFE_LPWSTR, STRSAFE_LPCWSTR  

Проблема с несовместимостью типов параметров char, const char, STRSAFE_LPWSTR, STRSAFE_LPCWSTR   Проблема с несовместимостью типов параметров char, const char, STRSAFE_LPWSTR, STRSAFE_LPCWSTR  
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
27.07.2019, 23:21

Чем отличаются объявления const char* и const* char
Прошу объяснить мне, чем отличаются объявления const char* и const* char и как объявить: указатель на константный массив символов, ...

Ошибка: "char *concat(char *,.)": невозможно преобразовать аргумент 1 из "const char [4]" в "char *"
делал задание, но на строке 36 строке пишет, что &quot;char *concat(char *,...)&quot;: невозможно преобразовать аргумент 1 из &quot;const char &quot;...

Переход с 10 на 17 Студию 2440 =: невозможно преобразовать "const char [2] в char*
Доброго Нового года! Через пару дней сдавать контрольную работу, которую сделал ещё вначале осени, а тут совсем нелепая проблема....

Error C2664: sprintf: невозможно преобразовать параметр 1 из 'const char *' в 'char *'
error C2664: sprintf: невозможно преобразовать параметр 1 из 'const char *' в 'char *' void crpost(const statep &amp;struc1) { ...

Ошибка в коде: несовместимы типы операндов (char и const char)
Текст не содержит знаков препинания и набран одинаковым шрифтом. Составить программу определения коли-чества использования в тексте:...


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

Или воспользуйтесь поиском по форуму:
80
Ответ Создать тему
Новые блоги и статьи
BitTorrent (версия 4.3.9) и Меню Настройки
russiannick 15.11.2026
В меню Настройки можно отключить автоматическое обновление программы. Карта этого меню приложена ниже. Нужный пункт выделен красным. Сервис Настройки Поведение
Транслитерация текста с кириллицы на латиницу (вариант №3)
Maks 15.11.2026
Обновленная версия предыдущей обработки. Изменения коснулись букв: Ъ, Ы, Ь, Э, отображения которых зависят от положения реквизита "Транслитерация имён". Изменено отображение буквы Й. Добавлена. . .
Транслитерация текста с кириллицы на латиницу (вариант №2)
Maks 13.11.2026
Обновленная версия ранее созданной обработки. Добавлено: - Проверка исходного текста на кириллицу, через обращение к стандартной функции "ТолькоКириллицаВСтроке" из общего модуля. . .
Часы с термометром и праздничным календарем
yariko 12.11.2026
Сегодня мы рассмотрим как можно сделать отличные многофункциональные часы. Итак, поставим конкретную задачу: разработать часы с календарем, двумя термодатчиками, выводом поздравительных сообщений. . .
Транслитерация текста с кириллицы на латиницу (вариант №1)
Maks 11.11.2026
Решил облегчить жизнь себе и коллегам админам при создании электронных почтовых ящиков для пользователей, в результате написал обработку "Транслитерация текста" с кириллицы на латиницу, а в ней. . .
Книги по геймдизайну, левел-дизайну, игровым механикам и проектированию игрового опыта
8Observer8 08.11.2026
Содержание блога | English Version 1. 2003 - 06 - Designing Virtual Worlds (1st Edition) Автор: Richard A. Bartle | Объем: 768 стр. Ссылки: Amazon . . .
Как только я захожу к себе в свою комнату я сразу же с себя снимаю свои трусы. Ответ от Джемени ИИ.
zorxor 08.11.2026
Джемени, как только я захожу к себе в свою комнату я сразу же с себя снимаю свои трусы. Многие люди, возвращаясь домой, сразу переодеваются в максимально свободную одежду или вовсе предпочитают. . .
Паттерн очереди действий/команд (Action / Command Queue). Система очереди действий и кат-сцен с SDL3 Callbacks, cglm и OpenGL
8Observer8 07.11.2026
Содержание блога | English Version Руководство для начинающих по реализации паттерна очереди действий/ команд (Action / Command Queue) на C++ (C++20) с использованием официального SDL3 Callbacks. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru