Форум программистов, компьютерный форум, киберфорум
C для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.74/27: Рейтинг темы: голосов - 27, средняя оценка - 4.74
49 / 49 / 8
Регистрация: 17.07.2011
Сообщений: 380

Сокеты в VC++ 2008

13.01.2012, 14:49. Показов 5567. Ответов 14
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Привет всем.
Я делаю клиент и сервер.
Делаю по книге : Снейдер Й. - Эффективное программирование TCP-IP.
Там есть типа заготовки на клиента и сервер. Вот я по заготовке и делаю...

Возникли проблемы уже на начале, при том пишет что ошибки в подключаемых стандартных файлах : winsock2.h и ws2def.h.

Вот такой код у меня:
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
#include "stdafx.h"
#include <windows.h>
#include "winsock2.h"
 
#include <stdio.h>
#include <stdlib.h>
//#include <unistd.h>
#include <stdarg.h>
#include <string.h>
#include <errno.h>
#include <netdb.h>
#include <fcntl.h>
#include <time.h>
#include <socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "skel.h"
 
char *program_name;
 
int main( int argc, char **argv )
 
{
 
struct sockaddr_in local;
struct sockaddr_in peer;
}
Вот такие ошибки пишет(там в комментариях в некоторых местах указываю на какую строку ругается):

Ошибка 5 error C2143: синтаксическая ошибка: отсутствие "}" перед "константа" c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h 384

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Protocols.  The IPv6 defines are specified in RFC 2292.
//
typedef enum {
#if(_WIN32_WINNT >= 0x0501)
    IPPROTO_HOPOPTS       = 0,  // IPv6 Hop-by-Hop options
#endif//(_WIN32_WINNT >= 0x0501)
    IPPROTO_ICMP          = 1, // вот здесь на ошибку показывает
    IPPROTO_IGMP          = 2,
    IPPROTO_GGP           = 3,
#if(_WIN32_WINNT >= 0x0501)
    IPPROTO_IPV4          = 4,
#endif//(_WIN32_WINNT >= 0x0501)
 
// это далеко не полный текст этого файла. могу полный показать. как видно выше, это из include\ws2def.h
Ошибка 4 error C2011: sockaddr: переопределение типа "struct" c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h 206

C
1
2
3
4
5
6
7
8
9
10
typedef struct sockaddr { 
 
#if (_WIN32_WINNT < 0x0600)
    u_short sa_family;
#else 
    ADDRESS_FAMILY sa_family;           // Address family.
#endif //(_WIN32_WINNT < 0x0600)
 
    CHAR sa_data[14];                   // Up to 14 bytes of direct address.
} SOCKADDR, *PSOCKADDR, FAR *LPSOCKADDR;
А вот здесь вроде как и справедливая ошибка:
Ошибка 8 error C2143: синтаксическая ошибка: отсутствие ";" перед "}" c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h 437

C
1
2
3
4
5
6
7
8
//
//  These are reserved for internal use by Windows.
//
    IPPROTO_RESERVED_RAW  = 257,
    IPPROTO_RESERVED_IPSEC  = 258,
    IPPROTO_RESERVED_IPSECOFFLOAD  = 259,
    IPPROTO_RESERVED_MAX  = 260     // должна же тут быть ";" у меня что с ошибками файлы эти?
} IPPROTO, *PIPROTO;

Ошибка 9 error C4430: отсутствует спецификатор типа - предполагается int. Примечание. C++ не поддерживает int по умолчанию c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h 437
C
1
2
3
4
5
6
7
8
//
//  These are reserved for internal use by Windows.
//
    IPPROTO_RESERVED_RAW  = 257,
    IPPROTO_RESERVED_IPSEC  = 258,
    IPPROTO_RESERVED_IPSECOFFLOAD  = 259,
    IPPROTO_RESERVED_MAX  = 260
} IPPROTO, *PIPROTO; // вот на этой строке показывает error


Ошибка 64 error C2375: WSAStartup: переопределение; другая компоновка c:\program files\microsoft sdks\windows\v6.0a\include\winsock2.h 2145

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/* Microsoft Windows Extension function prototypes */
 
#if INCL_WINSOCK_API_PROTOTYPES
__control_entrypoint(DllExport)
WINSOCK_API_LINKAGE
int
WSAAPI
WSAStartup(
    IN WORD wVersionRequested,
    OUT LPWSADATA lpWSAData
    );
#endif /* INCL_WINSOCK_API_PROTOTYPES */
 
#if INCL_WINSOCK_API_TYPEDEFS
typedef
int
(WSAAPI * LPFN_WSASTARTUP)(
    IN WORD wVersionRequested,
    OUT LPWSADATA lpWSAData
    );// вот здесь на эту ошибку показывает
#endif /* INCL_WINSOCK_API_TYPEDEFS */

Ну вобщем вот такие ошибки и их всего 69.
Кстати, в VC++ в Проект/Свойства/Компоновщик/Общие/Дополнительные каталоги библиотек я поставил wsock32.lib , а также это я поставил wsock32.dll в Проект/Свойства/Компоновщик/Ввод/Добавить модуль в сборку (пробовал сюда ставить wsock32.lib вместо wsock32.dll , а также пробовал и то и другое ставить).

Подскажите, пожалуйста, что может быть не так. Просто я полный ноль в этом деле, уже 2 дня морочусь и никак не могу понять что до чего.

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

Заранее благодарю за внимание.
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
13.01.2012, 14:49
Ответы с готовыми решениями:

Отличие VS 2008 от VS 2008 в SQL Server 2008
Здравствуйте только начал изучать SQL! До этого работал в Visual Studio 2008(с++) и установил SQL Server 2008 В него входит пакет...

Php сокеты и unix-сокеты
Здравствуйте, есть программа, написанная на С под Linux. При её работе в памяти хранятся несколько массивов, которые необходимо обработать...

Нужна помошь в подключении SQL Server 2008 и Visual Studio 2008
Добрый день уважаемые форумчане... Мне нужна ВАША помощь... Я искал в инете кучу информации о подключении удаленного доступа.. Но там...

14
инженер-системотехник
 Аватар для Haster
111 / 111 / 5
Регистрация: 10.03.2009
Сообщений: 533
13.01.2012, 15:02
Как я понял, в файле windows.h уже подключается winsock2.h, если версия винды старше или равна XP.
А ты подключаешь его еще раз - в итоге возникают проблемы с переопределением.
Попробуй заккоментировать строку #include "winsock2.h"
1
49 / 49 / 8
Регистрация: 17.07.2011
Сообщений: 380
13.01.2012, 15:14  [ТС]
Цитата Сообщение от Haster Посмотреть сообщение
Как я понял, в файле windows.h уже подключается winsock2.h, если версия винды старше или равна XP.
А ты подключаешь его еще раз - в итоге возникают проблемы с переопределением.
Попробуй заккоментировать строку #include "winsock2.h"
Да , стало без ошибок, только еще вот нужно было закоментировать некоторые инклюды:

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
#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
//#include <unistd.h>
#include <stdarg.h>
#include <string.h>
#include <errno.h>
//#include <netdb.h>
//#include <socket.h>
#include <fcntl.h>
#include <time.h>
//
//#include <netinet/in.h>
//#include <arpa/inet.h>
//#include "skel.h"
 
char *program_name;
 
int main( int argc, char **argv )
 
{
 
struct sockaddr_in local;
struct sockaddr_in peer;
 
}
А вы не подскажете где можно прочесть о всем этом в жоступной форме? Видимо та книга действительно устарела. Там вобще почти готовый сервер, который должен работать, а с ним проблемы. Например если закоментировать инклюды, для которых пишет Ошибка 1 fatal error C1083: Не удается открыть файл include: socket.h: No such file or directory c:\documents and settings\vitalij\мои документы\visual studio 2008\projects\serv\serv\serv.cpp 13

ну и не только этот инклюд, а и другие... так вот, если их закоментировать чтобы не было ошибок, то оно потом не понимает что за функции вызываются, что за переменные используются.
0
инженер-системотехник
 Аватар для Haster
111 / 111 / 5
Регистрация: 10.03.2009
Сообщений: 533
13.01.2012, 15:25
Скиньте полный код сервера, посмотрю в чем могут быть проблемы...

Думаю, про подключение библиотек не в одной книге не написано в нормальном виде.
Тут просто нужно анализировать ошибки и искать причину.
Например, если в тексте ошики встречается слово redefine или redifination, то это говорит о том, что какой-то файл (не защищенный от повторного включения) скорей всего подключается дважды ну или есть объявления с одинаковыми именами.
Если компилятор не может найти какие-то файлы, то тут несколько вариантов:
1) файл находится в другом месте
2) файл из сторонней библиотеки и ее нужно поставить
3) исходники даны под другую платформу, например под Linux, а не под Windows
4) ...

Вот такая арифметика
0
49 / 49 / 8
Регистрация: 17.07.2011
Сообщений: 380
13.01.2012, 15:33  [ТС]
Там закоментирован весь код в main , но если его раскоментировать, то возникают такие проблемы что оно не понимает откуда функции и откуда переменные (строки по которым идет описание указал на всякий случай):

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
#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
//#include <unistd.h>
#include <stdarg.h>
#include <string.h>
#include <errno.h>
//#include <netdb.h>
#include <socket.h>
#include <fcntl.h>
#include <time.h>
//
//#include <netinet/in.h>
//#include <arpa/inet.h>
//#include "skel.h"
 
char *program_name;
 
int main( int argc, char **argv )
 
{
 
struct sockaddr_in local;
struct sockaddr_in peer;
 
/*
char *hname;
char *sname;
int peerlen;
SOCKET s1;
SOCKET s;
const int on = 1;
 
 
25 INIT ();       .......................................................................................
 
26 if ( argc == 2 ) ..........................................................................
{
hname = NULL;
sname = argv[ 1 ];
}
 
else
{
hname = argv[ 1 ];
sname = argv[ 2 ];
}
 
36 set_address( hname, sname, &local, "tcp" ); ..................................................................
37 s = socket( AF_INET, SOCK_STREAM, 0 );.......................................................
 
if ( !isvalidsock( s ) )
error ( 1, errno, "ошибка вызова socket" );
 
if ( setsockopt( s, SOL_SOCKET, SO_REUSEADDR, &on,
sizeof( on ) ) )
error( 1, errno, "ошибка вызова setsockopt" ); 
 
if ( bind( s, ( struct sockaddr * ) klocal,
sizeof( local ) ) )
error( 1, errno, "ошибка вызова bind" );
 
46 if ( listen ( s, NLISTEN ) ).........................................................................................
error( 1, errno, "ошибка вызова listen" );
 
48 do ...................................................................................................................
{
peerlen = sizeof( peer );
s1 = accept( s, ( struct sockaddr * )&peer, &peerlen );
if ( !isvalidsock( s1 ) )
error( 1, errno,  "ошибка вызова accept" );
server( s1, &peer );
CLOSE( s1 );
} while ( 1 );
 
 
EXIT( 0 );
}
 
 
 
static void set_address(char *hname, char *sname,
struct sockaddr_in *sap, char *protocol)
 
{
struct servant *sp;
struct hostent *hp;
char *endptr;
short port;
 
bzero (sap, sizeof(*sap));
sap->sin_family = AF_INET;
 
if (hname != NULL)
{
if (!inet_aton (hname, &sap->sin_addr))
{
hp = gethostbyname(hname);
 
if ( hp == NULL )
error( 1, 0, "неизвестный хост: %s\n", hname );
sap->sin_addr = *( struct in_addr * )hp->h_addr;
}
 
}
 
else
 
sap->sin_addr.s_addr = htonl( INADDR_ANY );
port = strtol( sname, &endptr, 0 );
if ( *endptr == '\0' )
sap->sin_port = htons( port );
 
else
{
sp = getservbyname( sname, protocol );
if ( sp == NULL )
error( 1, 0, "неизвестный сервис: %s\n", sname );
sap->sin_port = sp->s_port;
}
 
}
 
 
 
void error( int status, int err, char *fmt,  ... )
 
{
va_list ap;
va_start ( ар, fmt );
fprintf (stderr, "%s: ", program_name );
vfprintf( stderr, fmt, ap ) ;
va_end( ap ) ;
 
if ( err )
fprintf( stderr, ": %s (%d)\n", strerror( err ), err);
 
if ( status )
EXIT( status );
 
*/
 
}

Вот описания автора (Снейдера):


Включаемые файлы и глобальные переменные

1-14 Включаем заголовочные файлы, содержащие объявления используе*мых стандартных функций.

25 Макрос INIT выполняет стандартную инициализацию, в частности, установку глобальной переменной program_name для функции error и вызов функции WSAStartup при работе на платформе Windows.

Функция main

26-35 Предполагается, что при вызове сервера ему будут переданы адрес и номер порта или только номер порта. Если адрес не указан, то привязываем к сокету псевдоадрес INADDR_ANY, разрешающий прием соединений по любому сетевому интерфейсу. В настоящем приложении в командной строке могут, конечно, быть и другие аргументы, обрабатывать их надо именно в этом месте.

36 Функция set_address записывает в поля переменной local типа sockaddr_in указанные адрес и номер порта. Функция set_address показана в листинге 2.3.

37-45 Получаем сокет, устанавливаем в нем опцию SO_REUSEADDR (совет 23) и привязываем к нему хранящиеся в переменной local адрес и номер порта.

46-47 Вызываем listen, чтобы сообщить ядру о готовности принимать соединения от клиентов.

48-56Принимаем соединения и для каждого из них вызываем функцию server. Она может самостоятельно обслужить соединение или создать Для этого новый процесс. В любом случае после возврата из функции server соединение закрывается.

Вот такие вот дела...
0
инженер-системотехник
 Аватар для Haster
111 / 111 / 5
Регистрация: 10.03.2009
Сообщений: 533
13.01.2012, 15:44
Ну у тебя в коде полно ошибок, какие-то левые симолы, точки, числа...
Сейчас попробую почистить
0
49 / 49 / 8
Регистрация: 17.07.2011
Сообщений: 380
13.01.2012, 15:48  [ТС]
Цитата Сообщение от Haster Посмотреть сообщение
Ну у тебя в коде полно ошибок, какие-то левые симолы, точки, числа...
Сейчас попробую почистить
А это я поставил числа чтобы было видно где начинается строка, про которую идет описание под кодом. А точками выделил эту строку, чтобы проще было находить листая. но когда их не было оно тоже не работало.
0
инженер-системотехник
 Аватар для Haster
111 / 111 / 5
Регистрация: 10.03.2009
Сообщений: 533
13.01.2012, 15:57
Так, походу где-то раньше в книге создавались необходимые файлы. Попробуй поискать
0
49 / 49 / 8
Регистрация: 17.07.2011
Сообщений: 380
13.01.2012, 16:40  [ТС]
Цитата Сообщение от Haster Посмотреть сообщение
Так, походу где-то раньше в книге создавались необходимые файлы. Попробуй поискать
там перед самой прогой вот такой заголовочный файл был создан:

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
#ifndef __SKEL_H__
 
#define __SKEL_H__
 
/*версия для UNIX */
 
#define INIT() ( program_name = \
 
strrchr ( argv[ 0 ], '/' ) ) ? \
 
program_name++ : \
 
( program_name = argv[ 0 ] )
 
#define EXIT(s) exit( s )
 
#define CLOSE(s) if ( close( s ) ) error( 1, errno, \
 
                     "ошибка close " )
 
#define set_errno(e) errno = ( e )
 
#define isvalidsock(s) ( ( s ) >= 0 )
 
typedef int SOCKET;
 
#endif /* __SKEL_H__ */
Чтобы сделать программы переносимыми, следует определить несколько макросов, в которых скрыть различия между API систем UNIX и Windows. Например, в UNIX системный вызов для закрытия сокета называется close, а в Windows - closesocket. Версии этих макросов для UNIX показаны в листинге 2.1. Версии для Windows аналогичны, приведены в приложении 2. Доступ к этим макросам из каркасов осуществляется путем включения файла skel.h( это вышеприведенный код)
Вот здесь в комментах написано что для UNIX, а в приложении 2 аналогичные команды для Виндовс. Я правильно поинмаю - мне нужно в этом месте заменить Виндосовскими командами и создать заголовочный файл.

Я бы не спрашивал, а попробовал бы, но просто я никогда не делал заголовочные файлы и для меня это проблема. Если это действительно надо, то займусь. просто сроки крайне поджимают - завтра утром к преподу на консультацию и нужно что-то принести хоть.

Да, как-то я прошлепал с этим файлом. Видимо от недосыпания уже начинаются приколы ... надо будет выспаться...
0
инженер-системотехник
 Аватар для Haster
111 / 111 / 5
Регистрация: 10.03.2009
Сообщений: 533
13.01.2012, 17:05
Лучший ответ Сообщение было отмечено как решение

Решение

Короче, если не хочешь возиться с доп. файлами, то вот все в одном: по крайней мере запускается,
но про корректность молчу (да, чтобы прога не падала - нужно задавать как минимум один параметр в командной строке)
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
//#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
//#include <unistd.h>
#include <stdarg.h>
#include <string.h>
#include <errno.h>
//#include <netdb.h>
//#include <socket.h>
#include <fcntl.h>
#include <time.h>
//
//#include <netinet/in.h>
//#include <arpa/inet.h>
/*âåðñèÿ äëÿ WINDOWS */
#define INIT() ( program_name = \
                    strrchr ( argv[ 0 ], '/' ) ) ? \
                    program_name++ : \
                    ( program_name = argv[ 0 ] )
 
#define EXIT(s) exit(s)
#define CLOSE(s) if (closesocket(s)) error( 1, errno, "îøèáêà âûçîâà close")
 
#define set_errno(e) SetLastError(e)
#define isvalidsock(s) ( ( s ) != SOCKET_ERROR )
#define bzero(b,n) memset(b,0,n)
#define sleep(t) Sleep( ( t ) * 1000 )
 
char *program_name = 0;
 
 
void error( int status, int err, char *fmt, ...)
{
 
    va_list ap;
 
    va_start(ap, fmt);
 
    fprintf (stderr, "%s: ", program_name );
    vfprintf( stderr, fmt, ap ) ;
    va_end( ap ) ;
 
    if ( err )
        fprintf( stderr, ": %s (%d)\n", strerror( err ), err);
 
    if ( status )
        EXIT(status);
}
 
int inet_aton( char *cp, struct in_addr *pin ) 
{ 
    int re; 
 
    re = inet_addr( cp ); 
    if ( re == -1 && strcmp (cp, "255.255.255.255" ) ) 
        return 0; 
 
    pin->s_addr = re; 
 
    return 1; 
}
 
static void set_address(char *hname, char *sname, struct sockaddr_in *sap, char *protocol)
{
    struct servent *sp;
    struct hostent *hp;
    char *endptr;
    short port;
 
    bzero (sap, sizeof(*sap));
    sap->sin_family = AF_INET;
 
    if (hname != NULL)
    {
        if (!inet_aton (hname, &sap->sin_addr))
        {
            hp = gethostbyname(hname);
 
            if ( hp == NULL )
                error( 1, 0, "íåèçâåñòíûé õîñò: %s\n", hname );
            sap->sin_addr = *( struct in_addr * )hp->h_addr;
        }
 
    }
    else
        sap->sin_addr.s_addr = htonl( INADDR_ANY );
    
    port = strtol( sname, &endptr, 0 );
    if ( *endptr == '\0' )
        sap->sin_port = htons( port );
    else
    {
        sp = getservbyname( sname, protocol );
        if ( sp == NULL )
            error( 1, 0, "íåèçâåñòíûé ñåðâèñ: %s\n", sname );
        sap->sin_port = sp->s_port;
    }
}
 
static void server(SOCKET s, struct sockaddr_in *peerp)
{
 
 send( s, "hello, world\n", 13, 0);
 
}
 
 
 
void main( int argc, char **argv )
{
    struct sockaddr_in local;
    struct sockaddr_in peer;
 
 
    char *hname;
    char *sname;
    int peerlen;
    SOCKET s1;
    SOCKET s;
    const char on = 1;
 
    INIT ();
 
    if ( argc == 2 ) 
    {
        hname = NULL;
        sname = argv[ 1 ];
    }
    else
    {
        hname = argv[ 1 ];
        sname = argv[ 2 ];
    }
 
    set_address( hname, sname, &local, "tcp" ); 
    s = socket( AF_INET, SOCK_STREAM, 0 );
 
    if ( !isvalidsock( s ) )
        error ( 1, errno, "îøèáêà âûçîâà socket" );
 
    if ( setsockopt( s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof( on ) ) )
        error( 1, errno, "îøèáêà âûçîâà setsockopt" ); 
 
    if ( bind( s, ( struct sockaddr * ) &local, sizeof( local ) ) )
        error( 1, errno, "îøèáêà âûçîâà bind" );
 
    if ( listen ( s, SO_ACCEPTCONN ) )
        error( 1, errno, "îøèáêà âûçîâà listen" );
 
    do 
    {
        peerlen = sizeof( peer );
        s1 = accept( s, ( struct sockaddr * )&peer, &peerlen );
        if ( !isvalidsock( s1 ) )
            error( 1, errno,  "îøèáêà âûçîâà accept" );
        server( s1, &peer );
        CLOSE( s1 );
    } 
    while ( 1 );
 
    EXIT( 0 );
}
Как ты уже понял, сорцы действительно под UNIX, поэтому и получается ерунда - в винде немного по другому инициализируются сокеты. В общем, я б тебе советовал найти нормальный пример под Windows. Думаю в сети это не проблема

Вот например тут: http://www.netlib.narod.ru/lib... h14_08.htm
4
49 / 49 / 8
Регистрация: 17.07.2011
Сообщений: 380
13.01.2012, 20:17  [ТС]
Haster, спасибо большое ! Буду разбираться.

На счет примеров, то нашел несколько примеров и объяснений, но все равно трудно разобраться:
http://citforum.ru/book/cook/winsock.shtml
http://www.intuit.ru/department/network/pami/4/
http://www.helloworld.ru/texts... vc2/16.htm

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

Хотел попробовать сделать по этим описаниям, но все таки смотрю придется примеры подходящие искать(кстати не так оно и сразу находится. еще раз спасибо за пример. как раз следудующая лаба заключается в том, чтобы создать подобное приложение как там).

еще вычитал что неплохо объясняется в "Системное программирование в среде Windows" Джонсон М. Харт. Ну не знаю , буду смотреть.
0
инженер-системотехник
 Аватар для Haster
111 / 111 / 5
Регистрация: 10.03.2009
Сообщений: 533
14.01.2012, 00:49
По первой ссылке (citforum) )вроде не плохой пример эхо TCP-сервера и клиента )
0
49 / 49 / 8
Регистрация: 17.07.2011
Сообщений: 380
16.01.2012, 02:11  [ТС]
Цитата Сообщение от Haster Посмотреть сообщение
По первой ссылке (citforum) )вроде не плохой пример эхо TCP-сервера и клиента )
Ага , начал по нему делать) Все неплохо так объясняется. но обратно таки - только по этому не поймешь, потому преподу вчера ничего не понес ))) но это уже такое ...

Добавлено через 31 минуту
Делал по вышеуказанному примеру, но там небольшие ошибки. Нашел в чем проблема(там в цикле while сервера нужно было со скобками разобраться) , но все равно кое-что непонятно ... оно то работает, но все равно непонятность спокойствия не дает.

Вобщем вот такое(там в закоментированном буду указывать на моменты) :
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// ЭТО КЛИЕНТ
 
 #define sHELLO "Hello, Sailor"
 
    // отправляем клиенту приветствие , размер этого равен 14 и оно это выводит(где нужно)
    send(my_sock,sHELLO,sizeof(sHELLO),0); 
 
int bytes_recv;
    while( (bytes_recv=                       // должно принять отличное от 14 значение после 1-го раза
                 recv(my_sock,&buf[0],sizeof(buf),0))
                  && (bytes_recv !=SOCKET_ERROR)) 
    {
    printf("\nkol-vo posulaemux dannux=%d\n",bytes_recv); // показывает ВСЕГДА 14
    printf("\nsizeof(buf)=%d\n",sizeof(buf));
    send(my_sock,&buf[0],bytes_recv,0);
    bytes_recv=0;// обнуляю, а в следующем цикле показывает 14 ...
    }
Здесь не понятно почему постоянно там 14 ? Ведь оно обнуляется и в следующем цикле должно присваиваться новое значение ...

А вот код клиента:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int nsize;
 
    while((nsize=recv(my_sock,&buf[0],
                      sizeof(buf)-1,0)) // вот здесь показывает что надо считывать 1023 байта
                  !=SOCKET_ERROR) 
    {
     // ставим завершающий ноль в конце строки 
    buf[nsize]=0; // оно по идее должно поставить ноль на 1024-байт ...
 
    // выводим на экран 
    printf("S=>C:%s",buf); // почему здесь выводит только то, что я ввел? весь буфер не выводит ...
    printf("\n%d\n",nsize); // ну и здесь всегда 14 показывает ...
 
 
    // читаем пользовательский ввод с клавиатуры
    printf("S<=C:"); fgets(&buf[0],sizeof(buf)-1,
             stdin);
    printf("\nsizeof(buf)-1  %d\n",sizeof(buf)-1);
А вот здесь у меня такое понимание вещей(не правильное):
1.Оно считывает 1023 байта.
2.1024-й байт = 0;
3.Вывести должно символы которые я ввел и незаполненные области массива символов. А почему оно не выводит незаполненные? (printf("S=>C:%s",buf); ) . Ведь потому-что в конце введенного стоит ноль ... но как оно поставило его аккурат после того, как я все ввел? Это когда мы fgets'ом вводим оно автоматически ноль ставит? а вот когда принимает recv , то оно не принимает это ноль, потому нужно восполнять его. Я правильно понимаю? что-то не могу детального описания recv найти ...

4. Не должно показывать 14 ...
0
инженер-системотехник
 Аватар для Haster
111 / 111 / 5
Регистрация: 10.03.2009
Сообщений: 533
16.01.2012, 16:25
CJS, можешь выложить полные тексты?
Не понятно, у тебя в первом куске кода написано, что это клиент и во втором тоже ) Так где что? _))
По поводу fgets - то действительно, возвращается Си-строка, т.е. 0 в конце добавляется, а recv - как read, что прочитала, то и вернула.

С 14 байтами так не скажешь, нужно смотреть весь код. Может у тебя по ошибке массив объявлен длиной 14 байт или еще что.
В общем, код в студию )
0
49 / 49 / 8
Регистрация: 17.07.2011
Сообщений: 380
17.01.2012, 00:45  [ТС]
Цитата Сообщение от Haster Посмотреть сообщение
CJS, можешь выложить полные тексты?
Не понятно, у тебя в первом куске кода написано, что это клиент и во втором тоже ) Так где что? _))
По поводу fgets - то действительно, возвращается Си-строка, т.е. 0 в конце добавляется, а recv - как read, что прочитала, то и вернула.

С 14 байтами так не скажешь, нужно смотреть весь код. Может у тебя по ошибке массив объявлен длиной 14 байт или еще что.
В общем, код в студию )
А я его уже переделал. Но на всякий случай выложу - может кому-то понадобится.

Сервер возвращает клиенту то, что клиент отослал серверу. Если идет любое слово, а после него через пробел буква "а" или "s" , то сервер читает файлы и содержимое возвращает клиенту(просто по заданию нужно сервер снабдить функциями, ну я одну добавил, чтобы хоть на троечку было, а то времени уже нету).




Сервер:

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
#include "stdafx.h"
#include<iostream>
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
//#include <ws2_32.h>
#include <stdarg.h>
#include <string.h>
#include <errno.h>
//#include <netdb.h>
//#include <socket.h>
#include <fcntl.h>
#include <time.h>
#pragma comment(lib, "WS2_32.lib")
using namespace std;
 
 
#define MY_PORT 666
#define PRINTUSERS if(nclients) printf("%d user on-line\n" , nclients); else printf("No user ONLINE\n");
 
DWORD WINAPI SexToClient(LPVOID client_socket);
 
int nclients=0;
FILE *fp;
 
int main ()
{
 
    char buf[1024];
 
printf("SERVER TCP\n");
 
if (WSAStartup(0x0202, (WSADATA *) &buf[0]) )
{
  // Ошибка!
          printf("Error WSAStartup %d\n",
             WSAGetLastError());
      return -1;
    }
 
 
 // Шаг 2 - создание сокета
    SOCKET mysocket;
    // AF_INET     - сокет Интернета
    // SOCK_STREAM  - потоковый сокет (с
    //      установкой соединения)
    // 0      - по умолчанию выбирается TCP протокол
 
 if ((mysocket=socket(AF_INET,SOCK_STREAM,0))<0)
    {
      // Ошибка!
      printf("Error socket %d\n",WSAGetLastError());
      WSACleanup();
        // Деиницилизация библиотеки Winsock
      return -1;
    }
 
 
 // Шаг 3 связывание сокета с локальным адресом
    sockaddr_in local_addr;
    local_addr.sin_family=AF_INET;
    local_addr.sin_port=htons(MY_PORT);
             // не забываем о сетевом порядке!!!
    local_addr.sin_addr.s_addr=0;
             // сервер принимает подключения
             // на все IP-адреса
 
 
    // вызываем bind для связывания
    if (bind(mysocket,(sockaddr *) &local_addr,
                sizeof(local_addr)))
    {
      // Ошибка
      printf("Error bind %d\n",WSAGetLastError());
      closesocket(mysocket);  // закрываем сокет!
      WSACleanup();
      return -1;
    }
 
    // Шаг 4 ожидание подключений
    // размер очереди – 0x100
    if (listen(mysocket, 0x100))
    {
      // Ошибка
      printf("Error listen %d\n",WSAGetLastError());
      closesocket(mysocket);
      WSACleanup();
      return -1;
    }
 
    printf("Ogidanie podkljuchenij\n");
 
 
    // Шаг 5 извлекаем сообщение из очереди
    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);
 
      // вывод сведений о клиенте
      printf("+%s [%s] new connect!\n",
      (hst)?hst->h_name:"",
      inet_ntoa(client_addr.sin_addr));
      PRINTUSERS
 
      // Вызов нового потока для обслужвания клиента
      // Да, для этого рекомендуется использовать
      // _beginthreadex но, поскольку никаких вызов
      // функций стандартной Си библиотеки поток не
      // делает, можно обойтись и CreateThread
      DWORD thID;
      CreateThread(NULL,NULL,SexToClient,
              &client_socket,NULL,&thID);
    }
 
 return 0;
  }

Клиент :
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
#include "stdafx.h"
#include <stdio.h>
#include <string.h>
#include <winsock2.h>
#include <windows.h>
#include<conio.h>
#pragma comment(lib, "WS2_32.lib")
 
#define PORT 666
#define SERVERADDR "127.0.0.1"
 
 
 
 
 
int _tmain(int argc, _TCHAR* argv[])
{
char buf[1024];
    
 
printf("TCP CLIENT\n");
 
// Шаг 1 - инициализация библиотеки Winsock
    if (WSAStartup(0x202,(WSADATA *)&buf[0]))
    {
      printf("WSAStart error %d\n",WSAGetLastError());
      return -1;
    }
 
 
// Шаг 2 - создание сокета
    SOCKET my_sock;
    my_sock=socket(AF_INET,SOCK_STREAM,0);
    if (my_sock < 0)
    {
      printf("Socket() error %d\n",WSAGetLastError());
      return -1;
    }
 
    
    // Шаг 3 - установка соединения
 
    // заполнение структуры sockaddr_in
    // указание адреса и порта сервера
    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))
      // hst->h_addr_list содержит не массив адресов,
      // а массив указателей на адреса
      ((unsigned long *)&dest_addr.sin_addr)[0]=
        ((unsigned long **)hst->h_addr_list)[0][0];
      else 
      {
        printf("Invalid address %s\n",SERVERADDR);
        closesocket(my_sock);
        WSACleanup();
        return -1;
      }
 
    // адрес сервера получен – пытаемся установить
    // соединение 
    if (connect(my_sock,(sockaddr *)&dest_addr,
                sizeof(dest_addr)))
    {
      printf("Connect error %d\n",WSAGetLastError());
      return -1;
    }
 
    printf("Connect with %s succesful\n\
    Type quit for quit\n\n",SERVERADDR);
 
 
    
    
    
    // Шаг 4 - чтение и передача сообщений
    int nsize;
 
    while((nsize=recv(my_sock,&buf[0],
                      sizeof(buf)-1,0))
                  !=SOCKET_ERROR)
    {
      // ставим завершающий ноль в конце строки 
      buf[nsize]=0;
 
      // выводим на экран 
      printf("S=>C:%s",buf);
      printf("\n%d\n",nsize);
 
 
      // читаем пользовательский ввод с клавиатуры
      printf("S<=C:"); fgets(&buf[0],sizeof(buf)-1,
             stdin);
      printf("\nsizeof(buf)-1  %d\n",sizeof(buf)-1);
 
      // проверка на "quit"
      if (!strcmp(&buf[0],"quit\n"))
      {
        // Корректный выход
        printf("Exit...");
        closesocket(my_sock);
        WSACleanup();
        return 0;
      }
 
      // передаем строку клиента серверу
      send(my_sock,&buf[0],nsize,0);
    }
 
    printf("Recv error %d\n",WSAGetLastError());
    closesocket(my_sock);
    WSACleanup();
    return -1;
 
getch();
  }
Добавлено через 7 часов 6 минут
Хм ... там в сервере нужно еще вот эту DWORD WINAPI SexToClient(LPVOID client_socket) функцию добавить - только что пересматривал и заметил что недокопировал код... вобщем вот полная версия:


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
#include "stdafx.h"
#include<iostream>
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
//#include <ws2_32.h>
#include <stdarg.h>
#include <string.h>
#include <errno.h>
//#include <netdb.h>
//#include <socket.h>
#include <fcntl.h>
#include <time.h>
#pragma comment(lib, "WS2_32.lib")
using namespace std;
 
 
#define MY_PORT 666
#define PRINTUSERS if(nclients) printf("%d user on-line\n" , nclients); else printf("No user ONLINE\n");
 
DWORD WINAPI SexToClient(LPVOID client_socket);
 
int nclients=0;
FILE *fp;
 
int main ()
{
 
    char buf[1024];
 
printf("SERVER TCP\n");
 
if (WSAStartup(0x0202, (WSADATA *) &buf[0]) )
{
  // Ошибка!
          printf("Error WSAStartup %d\n",
             WSAGetLastError());
      return -1;
    }
 
 
 // Шаг 2 - создание сокета
    SOCKET mysocket;
    // AF_INET     - сокет Интернета
    // SOCK_STREAM  - потоковый сокет (с
    //      установкой соединения)
    // 0      - по умолчанию выбирается TCP протокол
 
 if ((mysocket=socket(AF_INET,SOCK_STREAM,0))<0)
    {
      // Ошибка!
      printf("Error socket %d\n",WSAGetLastError());
      WSACleanup();
        // Деиницилизация библиотеки Winsock
      return -1;
    }
 
 
 // Шаг 3 связывание сокета с локальным адресом
    sockaddr_in local_addr;
    local_addr.sin_family=AF_INET;
    local_addr.sin_port=htons(MY_PORT);
             // не забываем о сетевом порядке!!!
    local_addr.sin_addr.s_addr=0;
             // сервер принимает подключения
             // на все IP-адреса
 
 
    // вызываем bind для связывания
    if (bind(mysocket,(sockaddr *) &local_addr,
                sizeof(local_addr)))
    {
      // Ошибка
      printf("Error bind %d\n",WSAGetLastError());
      closesocket(mysocket);  // закрываем сокет!
      WSACleanup();
      return -1;
    }
 
    // Шаг 4 ожидание подключений
    // размер очереди – 0x100
    if (listen(mysocket, 0x100))
    {
      // Ошибка
      printf("Error listen %d\n",WSAGetLastError());
      closesocket(mysocket);
      WSACleanup();
      return -1;
    }
 
    printf("Ogidanie podkljuchenij\n");
 
 
    // Шаг 5 извлекаем сообщение из очереди
    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);
 
      // вывод сведений о клиенте
      printf("+%s [%s] new connect!\n",
      (hst)?hst->h_name:"",
      inet_ntoa(client_addr.sin_addr));
      PRINTUSERS
 
      // Вызов нового потока для обслужвания клиента
      // Да, для этого рекомендуется использовать
      // _beginthreadex но, поскольку никаких вызов
      // функций стандартной Си библиотеки поток не
      // делает, можно обойтись и CreateThread
      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 buf[1024], s;
    #define sHELLO "Hello, Sailor"
 
    // отправляем клиенту приветствие 
    send(my_sock,sHELLO,sizeof(sHELLO),0);
 
    // цикл эхо-сервера: прием строки от клиента и
    // возвращение ее клиенту
    
    //while( int bytes_recv=recv(my_sock,&buf[0],sizeof(buf),0)&& bytes_recv !=SOCKET_ERROR)
    int bytes_recv;
        while( (bytes_recv=
                 recv(my_sock,&buf[0],sizeof(buf),0))
              && (bytes_recv !=SOCKET_ERROR))
    {
    /*  printf("\nkol-vo posulaemux dannux=%d\n",bytes_recv);
        printf("\nsizeof(buf)=%d\n",sizeof(buf)); */
 
        printf("%d", strlen(buf));
        for(int ii=0; ii<strlen(buf)-1;ii++){
            if(buf[ii]==' '){               
            s=buf[ii+1];
            break;
            }
        }
                switch(s)
                {
                case 's':
                fp=fopen("C:/Documents and Settings/Vitalij/staffs.txt","r");
                fgets(buf,200,fp);
                //printf("\n%s\n",buf);         
                break;
 
                case 'a':
                fp=fopen("C:/Documents and Settings/Vitalij/avtoparc.txt","r");
                fgets(buf,200,fp);
            //  printf("\n%s\n",buf);           
                break;
                }
 
 
        send(my_sock,&buf[0],strlen(buf),0);
        bytes_recv=0;
    }
     
 
    // если мы здесь, то произошел выход из цикла по
    // причине возращения функцией recv ошибки –
    // соединение клиентом разорвано
    nclients--; // уменьшаем счетчик активных клиентов
    printf("-disconnect\n"); PRINTUSERS
 
    // закрываем сокет
    closesocket(my_sock);
    return 0;
  }
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
17.01.2012, 00:45
Помогаю со студенческими работами здесь

Visual Studio 2008+ MS SQL Server 2008 добавления записей
Доброго времени суток господа! У меня возникла такая проблема : ключевое поле в таблице у меня индексированное с автоматическим приращением...

OC Window Server 2008(64)+1CV81 Сервер(64)+SQL 2008 (EXPRESS)
Все ставил по умолчанию т.е. на C:\ Установил 1СV81 платформу - полет нормальный Установил 1СV81 сервер – полет нормальный Установил...

Если проект создала в Visual C++ Express 2008, он должен запуститься просто в VS 2008?
Извините за глупый вопрос, просто времени нет устанавливать и проверять( Очень спешу

В VB 2008 не подключается база данных из MS SQL 2008
У меня есть готовая программа на VB 2008 и для её работы нужно подключить БД из MS SQL Server 2008, но при попытке подключения выдает вот...

БД в SQL SERVER 2008 и Visual Studio 2008
Всем доброго времени суток =))) БД автоматически была сгенерирована из ERWIN 7 в SQL SERVER 2008. А задача передо мной стоит такая: мне...


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

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru