I still suffer with the study of WinSock. It has long been possible to send a command to the server, but now it is impossible to get an answer from it. The buffer writes some kind of garbage.

Given: File Unit1.cpp , sendrecieve.cpp , sendrecieve.h .
Required: after sending the command getstatus to the server, get a string with all server parameters.

Unit1.cpp :
The code is listed in the second timer.

char buf[1024]; sendCMD(); receiveINF(buf); Memo1->Lines->Add(AnsiString(buf)); 

sendrecieve.h :
Two variables for the sockaddr_in structure for the sendCMD function, which sends the getstatus command to the server and information transfer / receive function headers.

 extern char *serverIP; extern int serverPORT; void sendCMD(); void sendCMD(char *command); void receiveINF(char *buf); 

sendrecieve.cpp :
In the receiveINF (char * buf) function, I tried to receive a socket, and in addition that it was asynhorn. The buffer, as I wrote above, is some kind of garbage. Somewhere I am doing something wrong. But I can not understand where.

 #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,0), &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 определен) //ps эту функцию взял на просторах msdn и интернета, по этому не понял, что это //за зверь. Может есть на что её поменять? WSAAsyncSelect(RecvSocket, Application->Handle, WM_ONSOCKET, FD_READ); // Вызываем функцию для приема датаграм iResult = recvfrom(RecvSocket, buf, 1024, 0, (SOCKADDR *) & RecvAddr, &RecvAddrSize); if (iResult == SOCKET_ERROR) { ShowMessage("Ошибка приема"); } // Закрываем сокет, когда приняли датаграммы iResult = closesocket(RecvSocket); if (iResult == SOCKET_ERROR) { ShowMessage("Ошибка закрытия сокета"); } //Очищаем все за собой, и выходим WSACleanup(); } 

Actually, the jamb is as follows: When I launch the program, nothing is written in Memo1, but if I move the mouse to some window or any button, any garbage will be written, apparently, from the buffer. And if you hover the cursor on the button, and nowhere to remove it, then the so-called. the garbage will be the same all the time. Sometimes, the truth skips the "garbage", which I seem to need - it starts with the junk and then the junk (yayaya, these are FF bytes in the UDP packet, more precisely, \ xff \ xff \ xff \ xff). And the question is - do I actually add the buffer correctly? :) Although I did strcat, I read everything from it in the memo.

  • one
    Something I did not notice bind (). From which port do you read recvfrom ()? - avp
  • Bind was, but I removed it. He is needed because if I am a server, or not? At least, somewhere saw implementation without it. And in principle, when he was, it was all the same. - DizzWebS
  • Exactly, now he looked with a sniffer, he sends getstatus, then via ICMP sends all the information that came from the server back to him, and the package says Destanation Unreachable. I will deal with the bind now. - DizzWebS
  • By the way, it's interesting - my sendto command creates a socket, sends a message to the server, closes the socket, clears it. By the same principle, the function of receiving a packet from the server also operates. Maybe this is the problem? That the initial socket from which it was sent is closed and the function does not know the port on which to send the packet. - DizzWebS
  • Of course, the port must be specified - Andrey Kuzmenko

1 answer 1

  SOCKET UDP = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP) char* val="1";//Это мой старый код хоть убей не помню зачем эта строка setsockopt(UDP, SOL_SOCKET, SO_BROADCAST, val, sizeof(val)); sockaddr_in UDP_addr; UDP_addr.sin_family = AF_INET; UDP_addr.sin_addr.S_un.S_addr = INADDR_ANY; UDP_addr.sin_port = htons(listenport); if( bind(UDP, (sockaddr*)&UDP_addr, sizeof(UDP_addr) ) != SOCKET_ERROR ) { cout<<"ok"<<endl; } else cout<<"error: "<<WSAGetLastError()<<endl; //тут при бинде для прослушивании могут возникать куча ошибок типа порт занят или что-то ещё int r = recvfrom(UDP, buff,sizeof(buff),0, (LPSOCKADDR)&cl, &s); if( r != SOCKET_ERROR) cout<<"buff = "<<buff<<endl; closesocket(UDP); 

Here is a part of my code, maybe it will help you. I just threw packets on Broadcast so I can’t say specifically about the code with listening to datagrams from a specific server that I don’t say so in your code. If I need to throw out all. Maybe garbage is due to your beast ( WSAAsyncSelect(RecvSocket, Application->Handle, WM_ONSOCKET, FD_READ); ) and because you don’t specifically point out which port to listen to.

  • In principle, your example is the same as everywhere else practically :) But I do not need broadkast. But still there are a couple of questions that I don’t understand a bit - listenport is this (and indeed) you have the port that you will be using on your system? Or is it a port from which infa should come? (I tend to the first :)) And this: (LPSOCKADDR) what is it? I just have a little differently written, I don’t know what it means. - DizzWebS
  • And I did WSAAsyncSelect, so that my interface would not stick - the function became asynchronous. I read that you can still make the receive function in the stream. If now I do not understand, tomorrow I will try the stream. - DizzWebS
  • And what vases for the variable cl? - DizzWebS
  • one
    1) the port that you will bind on your system to which infa will come 2) And I did WSAAsyncSelect, so that my interface would not stick - the function became asynchronous. instead, create a stream and let the code in this stream accept anything and the program will not stick 3) sockaddr_in cl; this structure will contain the address from whom the datagram came - Andrey Kuzmenko
  • one
    In my opinion, instead of streams, it is better to use select () for sockets listening to different ports. If at the same time you want to receive packets and wait for input not from the socket, then in Windows (as far as I can see, talking about it), unfortunately, you will probably have to create a stream. In general, it is difficult to debug programs with threads in practice. - avp