С Новым годом! Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.76/96: Рейтинг темы: голосов - 96, средняя оценка - 4.76
44 / 2 / 0
Регистрация: 12.11.2009
Сообщений: 40

И снова WinSock. UDP. Прием данных.

05.05.2011, 22:10. Показов 17817. Ответов 16
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
До сих пор мучаюсь с изучением WinSock. Уже давно получилось послать команду серверу, но теперь не получается получить от него ответ. Буфер пишет какой-то мусор.
Дано: файл Unit1.cpp, sendrecieve.cpp, sendrecieve.h.
Требуется: после отправки серверу команды getstatus получить строку со всякими параметрами сервера.

Unit1.cpp:
Код занесен в секундный таймер.
C++
1
2
3
4
char buf[1024];
sendCMD();
receiveINF(buf);
Memo1->Lines->Add(AnsiString(buf));
sendrecieve.h:
Две переменные для структуры sockaddr_in для функции sendCMD, которая посылает команду getstatus серверу и заголовки функций передачи/приема инфы.

C++
1
2
3
4
5
6
extern char *serverIP;
extern int serverPORT;
 
void sendCMD();
void sendCMD(char *command);
void receiveINF(char *buf);
sendrecieve.cpp:
В функции receiveINF(char *buf) я попробовал сделать прием сокета, и вдобавок чтобы он был асинхорнный. В буфер, как я уже писал выше, идет какой-то мусор. Где-то я что-то делаю не так. Вот только не могу понять, где.
p.s. немного поразбиравшись прикрутил bind() но толку пока ноль.
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
#include <vcl.h>
#include "sendreceive.h"
#include <winsock2.h>
 
#define WM_ONSOCKET WM_USER+1
 
void sendCMD()
{
    ...
}
 
void sendCMD(char *command)
{
    ...
}
 
void receiveINF(char *buf)
{
    int iResult = 0;
 
    WSADATA wsd;
    SOCKET RecvSocket;
 
    struct sockaddr_in RecvAddr;
    int RecvAddrSize = sizeof (RecvAddr);
 
// Инициализируем сокет
    iResult = WSAStartup(MAKEWORD(2,2), &wsd);
    if (iResult != NO_ERROR)
    {
        ShowMessage("WSAStartup filed");
    }
 
// Создаем принимающий сокет для приема датаграм
    RecvSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if (RecvSocket == INVALID_SOCKET)
    {
        ShowMessage("Socket failed");
    }
 
//ВЫЗЫВАЕМ ФУНКЦИЮ, которая сделает нашу функцию АСИНХРОННОЙ. Где-то тут  
//точно есть косяк, о нём после описания данного файла. Скорее всего
//это: Application->Handle надо чем-то заменять. 
//И еще я не разобрался, что же такое WM_ONSOCKET (сверху он в define определен)
//p.s. эту функцию взял на просторах msdn и интернета, по этому не понял, что это
//за зверь. Может есть на что её поменять?
    WSAAsyncSelect(RecvSocket, Application->Handle, WM_ONSOCKET, FD_READ);
 
// Биндим адрес к определенному порту и любому IPшнику
 
    RecvAddr.sin_family = AF_INET;
    RecvAddr.sin_port = htons(bindPORT);
    RecvAddr.sin_addr.s_addr = htonl(INADDR_ANY);
 
// Вызываем функцию для приема датаграм
    iResult = recvfrom(RecvSocket, buf, 1024, 0, (SOCKADDR *) & RecvAddr,
                                                               &RecvAddrSize);
    if (iResult == SOCKET_ERROR)
    {
        ShowMessage("Ошибка приема");
    }
 
// Закрываем сокет, когда приняли датаграммы
    iResult = closesocket(RecvSocket);
    if (iResult == SOCKET_ERROR)
    {
        ShowMessage("Ошибка закрытия сокета");
    }
 
//Очищаем все за собой, и выходим
    WSACleanup();
}
Собственно, косяк заключается в следующем: Когда запускаю программу, то в Memo1 ничего не пишется, но стоит мне мышкой навести на какое-нибудь окно, или кнопку любую, в Мемо1 будет писаться всякий мусор, видимо, из буфера. Причем если навести на кнопку курсор, и никуда не убирать его, то т.н. мусор будет все время одинаковый. Иногда, правда проскакивает "мусор", который, похоже, нужен мне - он начинается с юяяяя и дальше мусор (яяяя, это байты FF в UDP пакете, если точнее, то \xff\xff\xff\xff). Причем сейчас заметил, что иногда он, этот "мусор", приходит без юяяя. И вопрос - я вообще правильно буфер подсовываю? Хотя делал strcat, в мемо с него всё нормально прочиталось.

UPD #1: сейчас глянул сниффером, он посылает getstatus, потом по ICMP отсылает всю пришедшую с серва инфу ему назад, и в пакете написано - Destanation Unreachable.
У меня команда sendto создает сокет, отправляет сообщение серверу, сокет закрывает, очищает его. По этому же принципе действует и функция приема пакета с сервера. Может, в этом и есть проблема? Что начальный сокет, с которого посылалось, закрывается и функция не знает порт, на который прислать пакет.
Вот её (пока еще) БЫДЛОкод:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void sendCMD()
{
    WSADATA wsd;
    if (WSAStartup(MAKEWORD(2,2), &wsd)!=0)
    {
        ShowMessage("Не могу стартануть сокет"); 
    }
    else
    {
        SOCKET S;
        struct sockaddr_in servaddr;
        S=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
        servaddr.sin_family=AF_INET;
        servaddr.sin_port=htons(serverPORT);
        servaddr.sin_addr.s_addr=inet_addr(serverIP);
 
        char *buf = "\xff\xff\xff\xff getstatus";
        sendto(S,buf,strlen(buf),0,(SOCKADDR *) & servaddr, sizeof (servaddr));
        closesocket(S);
    }
 
    WSACleanup();
}
Подскажите, пожалуйста, где что не так, аа??? Я уже замучался с этими сокетами.

UPD #2: есть догадки, что надо как-то структуру эту всё время по новой не создавать, а что бы она централизованно где-то лежала. Хотя стоп... по идее при каждом новом коннекте надо же открывать новый сокет теоретически. Просто как мне оставить этот сокет открытым, но в от же время, что бы новые не создавались постоянно?
Еще одна догадка в том, что может надо забиндить прогу уже сразу в sendCMD? Хотя наврядли..

Добавлено через 32 минуты
UPD #3: народ подсказывает ещё, что лучше делать через поток. Как быть с этим в моём случае? что в поток "пихать"?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
05.05.2011, 22:10
Ответы с готовыми решениями:

UDP-сервер/клиент на Winsock
Доброго времени суток Есть UDP сервер и клиент, реализованные средствами winsock. Пока что все отрабатывается на одной машине, так что...

Прием данных в WinSock
Здравствуйте. Такой вопрос, в Winsock2_DataArrival (в самом низу кода) приходят данные с клиента (это приложение под Андроид, на нем есть...

Прием данных Winsock и преобразование данных Byte в String
VB.NET Здравствуйте! Вопрос! Есть обьект winsock для обмена сообщениями tcp\ip. http://vbbook.ru/1403703567/winsock-v-visual-basicnet/ ...

16
 Аватар для Maluda
1280 / 598 / 116
Регистрация: 18.08.2009
Сообщений: 832
06.05.2011, 02:00
Чем не устраивает TIdUDPServer?

Зачем так с WinSock извращаться?
0
44 / 2 / 0
Регистрация: 12.11.2009
Сообщений: 40
06.05.2011, 06:11  [ТС]
Что значит извращаться? По-моему всё нормально с WinSock. Indy-компоненты, как и вообще компоненты использовать не хочу, по этому делаю так. Тем более с Indy-компонентой я делал вначале, и она у меня постоянно глючила, поэтому нафиг, нафиг с ней ещё раз связываться. Ну а Вам, я вижу, просто хочется постов набить, ибо есть конкретные вопросы с просьбой объяснить, и ничего более. Спасибо, конечно, за поднятие темы, но лучше, что называется, по теме.
1
 Аватар для AlexSt
61 / 60 / 9
Регистрация: 13.01.2009
Сообщений: 322
06.05.2011, 11:15
из статьи Криса Касперски

Пример реализации UDP-сервера

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
  // Пример простого UDP-эхо сервера
  #include <stdio.h>
  #include <winsock2.h>
 
  #define PORT 666    // порт сервера
  #define sHELLO "Hello, %s [%s] Sailor\n"
 
  int main(int argc, char* argv[])
  {
    char buff[1024];
 
    printf("UDP DEMO echo-Server\n");
 
    // шаг 1 - подключение библиотеки 
    if (WSAStartup(0x202,(WSADATA *) &buff[0]))
    {
      printf("WSAStartup error: %d\n",
             WSAGetLastError());
      return -1;
    }
 
    // шаг 2 - создание сокета
    SOCKET my_sock;
    my_sock=socket(AF_INET,SOCK_DGRAM,0);
    if (my_sock==INVALID_SOCKET)
    {
      printf("Socket() error: %d\n",WSAGetLastError());
      WSACleanup();
      return -1;
    }
 
    // шаг 3 - связывание сокета с локальным адресом 
    sockaddr_in local_addr;
    local_addr.sin_family=AF_INET;
    local_addr.sin_addr.s_addr=INADDR_ANY;
    local_addr.sin_port=htons(PORT);
 
    if (bind(my_sock,(sockaddr *) &local_addr,
        sizeof(local_addr)))
    {
      printf("bind error: %d\n",WSAGetLastError());
      closesocket(my_sock);
      WSACleanup();
      return -1;
    }
 
    // шаг 4 обработка пакетов, присланных клиентами
    while(1)
    {
      sockaddr_in client_addr;
      int client_addr_size = sizeof(client_addr);
      int bsize=recvfrom(my_sock,&buff[0],
        sizeof(buff)-1,0,
        (sockaddr *) &client_addr, &client_addr_size);
      if (bsize==SOCKET_ERROR)
      printf("recvfrom() error: %d\n",
             WSAGetLastError());
 
      // Определяем IP-адрес клиента и прочие атрибуты
      HOSTENT *hst;
      hst=gethostbyaddr((char *)
            &client_addr.sin_addr,4,AF_INET);
      printf("+%s [%s:%d] new DATAGRAM!\n",
      (hst)?hst->h_name:"Unknown host",
      inet_ntoa(client_addr.sin_addr),
      ntohs(client_addr.sin_port));
 
      // добавление завершающего нуля
      buff[bsize]=0;
 
      // Вывод на экран 
      printf("C=>S:%s\n",&buff[0]);
 
      // посылка датаграммы клиенту
      sendto(my_sock,&buff[0],bsize,0,
        (sockaddr *)&client_addr, sizeof(client_addr));
    }
    return 0;
  }
Листинг 36 Пример реализации UDP-сервера

Пример реализации UDP-клиента

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
  // пример простого UDP-клиента
  #include <stdio.h>
  #include <string.h>
  #include <winsock2.h>
  #include <windows.h>
 
  #define PORT 666
  #define SERVERADDR "127.0.0.1"
 
  int main(int argc, char* argv[])
  {
    char buff[10*1014];
    printf("UDP DEMO Client\nType quit to quit\n");
 
    // Шаг 1 - иницилизация библиотеки Winsocks
    if (WSAStartup(0x202,(WSADATA *)&buff[0]))
    {
      printf("WSAStartup error: %d\n",
             WSAGetLastError());
      return -1;
    }
 
    // Шаг 2 - открытие сокета
    SOCKET my_sock=socket(AF_INET, SOCK_DGRAM, 0);
    if (my_sock==INVALID_SOCKET)
    {
      printf("socket() error: %d\n",WSAGetLastError());
      WSACleanup();
      return -1;
    }
 
    // Шаг 3 - обмен сообщений с сервером
    HOSTENT *hst;
    sockaddr_in dest_addr;
 
    dest_addr.sin_family=AF_INET;
    dest_addr.sin_port=htons(PORT);
 
    // определение IP-адреса узла
    if (inet_addr(SERVERADDR))
      dest_addr.sin_addr.s_addr=inet_addr(SERVERADDR);
    else
      if (hst=gethostbyname(SERVERADDR))
        dest_addr.sin_addr.s_addr=((unsigned long **)
              hst->h_addr_list)[0][0];
    else
      {
        printf("Unknown host: %d\n",WSAGetLastError());
        closesocket(my_sock);
        WSACleanup();
        return -1;
      }
 
    while(1)
    {
      // чтение сообщения с клавиатуры
      printf("S<=C:");fgets(&buff[0],sizeof(buff)-1,
             stdin);
      if (!strcmp(&buff[0],"quit\n")) break;
 
      // Передача сообщений на сервер
      sendto(my_sock,&buff[0],strlen(&buff[0]),0,
        (sockaddr *) &dest_addr,sizeof(dest_addr));
 
      // Прием сообщения с сервера
      sockaddr_in server_addr;
      int server_addr_size=sizeof(server_addr);
 
      int n=recvfrom(my_sock,&buff[0],sizeof(buff)-1,0,
        (sockaddr *) &server_addr, &server_addr_size);
 
      if (n==SOCKET_ERROR)
      {
        printf("recvfrom() error:"\
          "%d\n",WSAGetLastError());
        closesocket(my_sock);
        WSACleanup();
        return -1;
      }
 
      buff[n]=0;
 
      // Вывод принятого с сервера сообщения на экран
      printf("S=>C:%s",&buff[0]);
    }
 
    // шаг последний - выход
    closesocket(my_sock);
    WSACleanup();
 
    return 0;
  }
Листинг 37 Пример реализации UDP-клиента
По шагам проверь
1
 Аватар для kzru_hunter
1124 / 795 / 101
Регистрация: 01.02.2011
Сообщений: 1,887
Записей в блоге: 1
06.05.2011, 11:50
У меня с TNMUDP ничего не глючило. Тоже делал прогу для кс...
0
44 / 2 / 0
Регистрация: 12.11.2009
Сообщений: 40
06.05.2011, 13:55  [ТС]
AlexSt, спасибо, но этот код я уже, само собой, видел.
kzru_hunter, как уже писал выше, не хочу использовать компоненты. С Indy у меня вообще почти все идеально было, но вот из-за этого почти как раз и решил не мудрить, а написать свои функции для работы с сокетами.
0
 Аватар для Maluda
1280 / 598 / 116
Регистрация: 18.08.2009
Сообщений: 832
06.05.2011, 14:17
Embarcadero CBuilder 2010 работаю постоянно c UDP с помощью Indy никаких глюков ни разу не было!!!

Добавлено через 7 минут
ну и если не хочешь с компонентами,
работай с библиотекой ACE в Visual Studio - мощнее не бывает
0
44 / 2 / 0
Регистрация: 12.11.2009
Сообщений: 40
06.05.2011, 20:11  [ТС]
А, ну то есть, если с компонентами не хочу работать, то мне обязательно VS качать?
0
 Аватар для kzru_hunter
1124 / 795 / 101
Регистрация: 01.02.2011
Сообщений: 1,887
Записей в блоге: 1
07.05.2011, 05:43
Проще переделать под какой-нибудь компонент и задавать вопросы, когда возникает глюк.
0
 Аватар для Maluda
1280 / 598 / 116
Регистрация: 18.08.2009
Сообщений: 832
07.05.2011, 11:33
Просто смешно звучит, когда человек работает в CBUILDER и не хочет использовать компоненты.
Зачем ещё CBuilder тогда нужен???

А к Visual Studio ты рано или поздно прийдёшь, поверь моему опыту!!!
Когда столкнёшься с тем, что кроме компонентов никакие другие библиотеки к нему прикрутить нельзя.

Добавлено через 1 час 16 минут
Вот, держи Indy в консоли,
у себя проверил, всё работает.

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
// ***************** //
// Powered by MaZhor //
// ***************** //
#include <vcl.h>
#pragma hdrstop
 
#include <iostream>
#include <memory>
#include <tchar.h>
#include <IdUDPServer.hpp>
#include <IdUDPClient.hpp>
// ---------------------------------------------------------------------------
#pragma argsused
 
void __fastcall OnNotifyUDPRead(void*This, TIdUDPListenerThread* AThread,
    System::DynamicArray<System::Byte>AData,
    Idsockethandle::TIdSocketHandle* ABinding) {
    // обрабатываем приходящие данные
    std::wcout << BytesToString(AData, TEncoding::Default).c_str() << "\n";
}
 
int _tmain(int argc, _TCHAR* argv[]) {
    // ********************* //
    // СОЗДАНИЕ  UDP СЕРВЕРА //
    // ********************* //
    std::auto_ptr<TIdUDPServer>UDPServer(new TIdUDPServer(Application));
    UDPServer->DefaultPort = 3200;
    // приём сообщений будем производить в отдельном потоке
    UDPServer->ThreadedEvent = true;
    // создаём соединение
    TIdSocketHandle *Binding1 = UDPServer->Bindings->Add();
    Binding1->Port = 3200;
    Binding1->IP = "127.0.0.1";
    Binding1->IPVersion = Id_IPv4;
    // создаём метод с адресом нашей функции приёма сообщений
    TMethod MethodUDP;
    MethodUDP.Data = Application;
    MethodUDP.Code = OnNotifyUDPRead;
        // применяем метод к серверу
    UDPServer->OnUDPRead = *(TUDPReadEvent*)&MethodUDP;
    UDPServer->Active = true;
 
    // ********************* //
    // СОЗДАНИЕ  UDP КЛИЕНТА //
    // ********************* //
    std::auto_ptr<TIdUDPClient>UDPClient(new TIdUDPClient(Application));
    UDPClient->Port = 3200;
    UDPClient->Host = "127.0.0.1";
 
    // пока не будет нажата клавиша ESC будем слать данные на сервер
    while (GetKeyState(VK_ESCAPE) >= 0) {
        UDPClient->Send("test", TEncoding::Default);
        Sleep(16);
    }
 
    return 0;
}
// ---------------------------------------------------------------------------
0
44 / 2 / 0
Регистрация: 12.11.2009
Сообщений: 40
07.05.2011, 16:23  [ТС]
Цитата Сообщение от Maluda Посмотреть сообщение
Просто смешно звучит, когда человек работает в CBUILDER и не хочет использовать компоненты.
Зачем ещё CBuilder тогда нужен???

А к Visual Studio ты рано или поздно прийдёшь, поверь моему опыту!!!
Скажу по секрету, что нас в универе обучают работе на билдере, но так как я в дальнейшем планирую работать не только на нём, по этому мало того, что почти не юзаю компоненты, так еще и хочу иметь возможность портировать программу, к примеру, на тот же VS. И да, я и не сомневался, что столкнусь когда-нибудь с ним (быстрее бы это произошло). Ещё один момент, что моя хобби-программа с недавнего времени стала ещё и курсовой, по этому для меня сейчас важно (опять же, поставил цель себе я сам) написать именно так, как я хочу. Если не можете подтолкнуть маленько по вопросу, который я спросил, лучше ничего не писать. И хватит мне Indy уже предлагать... Тем более в Вашей функции, как я понимаю, только отправка серверу, что я вполне себе успешно реализовал. Проблема в правильном, а пока и вообще просто, получении инфы с сервера.
Извиняюсь за резкость, но просто достало, что все пытаются мне эти Indy впихнуть, в которых, кстати, отправка данных на сервер еще банальней, чем на чистых сокетах.
1
 Аватар для Maluda
1280 / 598 / 116
Регистрация: 18.08.2009
Сообщений: 832
07.05.2011, 17:01
Извини тоже за резкость, но ты ещё, как я вижу очень зеленый,
тебе знающие дяди, которые уже проехали всё это с бессонными ночами и красными глазами,
пытаются помочь сделать всё проще и быстрее.

Может ты ещё кросс-платформенности с winsock хочешь

Так вот, уважаемый, если ты хочешь портируемости,
то вот этого
C++
1
#include <vcl.h>
в VisualStudio не будет!!!!

И без этого не будет вот этого (это по твоему коду)
C++
1
AnsiString
C++
1
ShowMessage
C++
1
Application->Handle
А вот теперь отключи vcl.h и попробуй покодить :-)))

Просто, если у тебя задача стать профессионалом,
то тебе просто немедленно надо ставить VisualStudio и кодить именно в ней.
0
44 / 2 / 0
Регистрация: 12.11.2009
Сообщений: 40
07.05.2011, 19:22  [ТС]
Я не спорю, что зеленый, и в курсе, чего у меня не будет в ВСке (видимо, уже зелень выцветать начинает -) ). Ставить не буду, потому что есть проект уже весомый достаточно, переделывать точно пока не буду, из-за того, что он - курсач.
Конкретно по теме - попробую сегодня-завтра придумать что-нибудь, как в потоке сделать с Event, потом если не получится, попробую со стандартной UDP-компонентой. Наверное. Надеюсь, к Indy не придется возвращаться.
Кстати кроссплатформенность сделать для линукса не получится, потому что у меня сокеты 2.2 с определением пинга до сервера. Если, конечно, в лине сокеты не запилили)
0
 Аватар для Maluda
1280 / 598 / 116
Регистрация: 18.08.2009
Сообщений: 832
08.05.2011, 00:20
Да будешь вознаграждён ты за своё упрямство,
вот держи код по обмену сообщениями между сервером и клиентом на сокетах.
Обмен происходит в отдельных потоках,
в качестве потока использую TIdThreadComponent,
а если у тебя ненависть к инди, можешь использовать
TThread, boost::thread и т.д.

В общем, бросил на форму две кнопки TButton, TMemo и два TIdThreadComponent
По нажатию первой кнопки сервер слушает,
по нажатию второй кнопки - клиент отправляет и получает ответ от сервера.

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
// ---------------------------------------------------------------------------
AnsiString sDisplayString = "";
 
void __fastcall TForm1::DisplayInMemo() {
    Memo1->Lines->Add(sDisplayString);
}
 
// ---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender) {
    Memo1->Lines->Clear();
    // здесь я использую в качестве потока TIdThreadComponent
    // но если у тебя ненависть к Indy
    // можешь использовать <TThread> или <boost::thread>
    // в общем неважно, главное, чтобы это было в отдельном потоке
    IdThreadComponent1->Active = true;
}
 
// ---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender) {
    if (!IdThreadComponent1->Active) {
        ShowMessage("Server is not initialized!");
    }
    else {
        IdThreadComponent2->Active = true;
    }
}
 
 
// ---------------------------------------------------------------------------
void __fastcall TForm1::IdThreadComponent1Run(TIdThreadComponent *Sender) {
    WSADATA wData;
    struct sockaddr_in addr;
 
    if (WSAStartup(MAKEWORD(1, 1), &wData) != 0) {
        sDisplayString = "SERVER>socket is not initialized";
        Sender->Synchronize(&DisplayInMemo);
        WSACleanup();
        Sender->Active = false;
    }
    sDisplayString = "SERVER>socket is initialized";
    Sender->Synchronize(&DisplayInMemo);
 
    SOCKET listener = socket(AF_INET, SOCK_STREAM, NULL); // create socket
    sDisplayString = "SERVER>socket is created";
    Sender->Synchronize(&DisplayInMemo);
 
    addr.sin_family = AF_INET;
    addr.sin_port = htons(3000); // number port
    addr.sin_addr.s_addr = htonl(INADDR_ANY);
    int socket_name_size = sizeof(addr);
 
    if (bind(listener, (struct sockaddr*)&addr, socket_name_size) < 0) {
        sDisplayString = "SERVER>socket is not binded";
        Sender->Synchronize(&DisplayInMemo);
        shutdown(listener, 2);
        closesocket(listener);
        WSACleanup();
        Sender->Active = false;
    }
    sDisplayString = "SERVER>socket is binded";
    Sender->Synchronize(&DisplayInMemo);
 
    listen(listener, 1);
    sDisplayString = "SERVER>set listening";
    Sender->Synchronize(&DisplayInMemo);
 
    while (true) {
        SOCKET sock = accept(listener, NULL, NULL);
        if (sock < 0) {
            sDisplayString = "SERVER>accept error";
            Sender->Synchronize(&DisplayInMemo);
            break;
        }
 
        char buff[1024];
        int bytes_read = recv(sock, buff, 1024, 0);
        if (bytes_read < 0) {
            sDisplayString = "SERVER>bytes_read < 0";
            Sender->Synchronize(&DisplayInMemo);
            shutdown(sock, 2);
            closesocket(sock);
        }
 
        sDisplayString = "SERVER>Received text: " + AnsiString(buff);
        Sender->Synchronize(&DisplayInMemo);
 
        char buffer1[] = "Reply is sent from server!";
 
        send(sock, buffer1, sizeof(buffer1), 0);
 
        shutdown(sock, 2);
        closesocket(sock);
        break;
    }
    shutdown(listener, 2);
    closesocket(listener);
    WSACleanup();
 
    Sender->Active = false;
}
 
// ---------------------------------------------------------------------------
void __fastcall TForm1::IdThreadComponent2Run(TIdThreadComponent *Sender) {
    WSADATA wData;
    struct sockaddr_in addr, serv_addr;
 
    if (WSAStartup(MAKEWORD(1, 1), &wData) != 0) {
        sDisplayString = "CLIENT>socket is not initialized";
        Sender->Synchronize(&DisplayInMemo);
        WSACleanup();
        Sender->Active = false;
    }
    sDisplayString = "CLIENT>socket is initialized";
    Sender->Synchronize(&DisplayInMemo);
 
    SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock == -1) {
        sDisplayString = "CLIENT>socket is not created";
        Sender->Synchronize(&DisplayInMemo);
        WSACleanup();
        Sender->Active = false;
    }
 
    addr.sin_family = AF_INET;
    addr.sin_port = htons(3000);
    addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
    bind(sock, (struct sockaddr *)&addr, sizeof(addr));
 
    char HostName[1024];
    DWORD HostIP = 0;
    LPHOSTENT lphost;
    gethostname(HostName, 1024);
    lphost = gethostbyname(HostName);
    serv_addr.sin_family = AF_INET;
    memcpy((char*)&serv_addr.sin_addr, lphost->h_addr, lphost->h_length);
    serv_addr.sin_port = htons(3000);
 
    int error;
    if (connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) {
        sDisplayString = "CLIENT>connection error";
        Sender->Synchronize(&DisplayInMemo);
        shutdown(sock, 2);
        closesocket(sock);
        WSACleanup();
        Sender->Active = false;
    }
    sDisplayString = "CLIENT>connection success";
    Sender->Synchronize(&DisplayInMemo);
 
    char message1[] = "Test message for sending from client!";
    send(sock, message1, sizeof(message1), 0);
 
    sDisplayString = "CLIENT>Send a message: " + AnsiString(message1);
    Sender->Synchronize(&DisplayInMemo);
 
    char buff[1024];
    recv(sock, buff, sizeof(buff), 0);
    sDisplayString = "CLIENT>answer " + AnsiString(buff);
    Sender->Synchronize(&DisplayInMemo);
    recv(sock, buff, sizeof(buff), 0);
    sDisplayString = "CLIENT>answer " + AnsiString(buff);
    Sender->Synchronize(&DisplayInMemo);
 
    shutdown(sock, 2);
    closesocket(sock);
    WSACleanup();
    Sender->Active = false;
}
 
// ---------------------------------------------------------------------------
1
44 / 2 / 0
Регистрация: 12.11.2009
Сообщений: 40
08.05.2011, 08:23  [ТС]
Спасибо, по делу
Плюс покурю ещё немного маны на мсдн -)

Добавлено через 18 минут
Кстати у Вас не UDP, но принцип понял.
0
 Аватар для cpp_developer
20124 / 5691 / 417
Регистрация: 09.04.2010
Сообщений: 22,546
Записей в блоге: 1
08.05.2011, 08:24
Цитата Сообщение от Maluda Посмотреть сообщение
Просто, если у тебя задача стать профессионалом, то тебе просто немедленно надо ставить VisualStudio и кодить именно в ней.

Абсолютно не джентельментский совет в разделе C++ Builder. Имхо, если уж приспичило, приличные люди в подобных случаях используют услугу, которая называется Личные сообщения. Просто .
0
Эксперт С++
 Аватар для Avazart
8484 / 6151 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
11.08.2011, 03:11
У Indy просто свои нюансы они как то по особенному работают...
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
11.08.2011, 03:11
Помогаю со студенческими работами здесь

Прием данных по UDP
Добрый день! Пишу приложение для работы с контроллером по Ethernet. Возникла такая проблема. Данные с контроллера приходят в приложение...

Передача с микрофона в udp и прием из udp на динамик
Собственно каким образом осуществить передачу данных с микрофона в сеть и прием из сети данных вывести на звуковое устройство. проект...

UDP Winsock
Всем привет вот могу тока сделать функцию для отссылки на UDP сервер сообщение int PORT = 7777; AnsiString SERVERADDR =...

WinSock UDP по интернету
Доброго времени суток. У меня вечная проблема. Не работают у меня программы на WinSock'e по интернету, но они работают на одном компьютере...

Получение UDP в Winsock.
Здрасте все. Народ, кто знает как на VB открыть порт так чтобы в него можно было бы ловить UDP датаграммы, ну и соответственно и получать...


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

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
Новые блоги и статьи
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru