Я использую ОС Windows и в настоящее время пишу на C.
Я новичок в программировании сокетов, и у меня есть следующий фрагмент кода, который возвращает нежелательные значения.
(MAXLINE = 4096), и я определил CTR_SECURITY....
const char* IPADDRESS = "xxx.xxx.xx.xx";//IP address
int sockFileDescriptor = 0, n;
int sendbytes = 0;
SOCKADDR_IN servaddr = { 0 };
char sendl[MAXLINE];
char recvl[MAXLINE];
memset(sendl, 0, MAXLINE);
WSADATA wsa;
WSAStartup(MAKEWORD(2, 2), &wsa);
if (0 > (sockFileDescriptor = socket(AF_INET, SOCK_STREAM, 0))) {
printf("no socket");
exit(-1);
}
memset((char*)&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(1337);
int a = InetPton(AF_INET, IPADDRESS, &servaddr.sin_addr.S_un.S_addr);
if (0 >= a) {
printf("inetPton %d, returnV = %d", WSAGetLastError(), a);
exit(-1);
}
if (0 > connect(sockFileDescriptor, (SOCKADDR*)&servaddr, sizeof(servaddr))) {
printf("connect wrong %d", WSAGetLastError());
exit(-1);
}
sprintf(sendl, "GET / HTTP/1.1\r\n\r\n");
sendbytes = strlen(sendl);
/*
if (_write(sockFileDescriptor, sendl, sendbytes) != sendbytes) {
printf("error");
exit(-1);
}*/
if (0 > send(sockFileDescriptor, sendl, strlen(sendl), 0)) {
printf("sendGoneWrong");
exit(-1);
}
memset(recvl, 0, MAXLINE);
while ((n = _read(sockFileDescriptor, recvl, MAXLINE - 1))>0) {
printf("%s", recvl);
}
exit(0);
Оно возвращается "inetPton 10022, returnV = 0".
Я пробовал другие IP-адреса, но ни один из них не изменил результат, что заставило меня поверить, что я неправильно использую функцию InetPton().
Кстати, в InetPton() мне следует использовать servAddr.sin_addr или servaddr.sin_addr.S_un.S_addr?
Код ошибки Winsock 10022: WSAEINVAL (неверный аргумент). Обратите внимание, что WSAGetLastError()документировано как имеющее смысл только в том случае, если InetPton() возвращает -1, а не 0.
Кстати: если у вас это заработает, ваш код все равно потерпит неудачу, потому что вы отправляете запрос HTTP 1.1 без обязательного заголовка Host, например: "GET / HTTP/1.1\r\nHost: HostnameOrIP:1337\r\n\r\n". Почему вы делаете это вручную с помощью Winsock вместо того, чтобы использовать WinInet ? См. HTTP-сеансы.





Все это можно заменить:
memset((char*)&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(1337);
int a = InetPton(AF_INET, IPADDRESS, &servaddr.sin_addr.S_un.S_addr);
if (0 >= a) {
printf("inetPton %d, returnV = %d", WSAGetLastError(), a);
exit(-1);
}
С этим:
{
addrinfo *result = NULL;
addrinfo hints = { 0 };
int ret = 0;
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_NUMERICHOST;
ret = getaddrinfo(IPADDRESS, "1337", &hints, &result);
if (ret == 0 && result != NULL) {
memcpy(&servaddr, result->ai_addr, sizeof(servaddr));
freeaddrinfo(result);
}
}
Спасибо за ответ, но я думаю, что знаю слишком мало интернет-материалов, чтобы даже понять это.
Неправильный тип строки. IPADDRESS — указатель типа PCWSTR. Поэтому вам следует использовать PCWSTR или const wchar_t* для определения IPADDRESS.
Проверьте документ: https://learn.microsoft.com/en-us/windows/win32/learnwin32/working-with-strings
После изменения вы можете перейти к следующему шагу.
Хорошо, это удалось сделать, большое спасибо за небольшую таблицу и ссылки на документы.
@NWA_fan С удовольствием! Если это ответ, примите его в качестве руководства для тех, у кого такой же вопрос.
Вместо вызова InetPton() вам следует вызвать inet_pton(), который принимает строку const char*.
Ожидается, что последний аргумент будет структурой
in_addr. Так что вам остаётся только пройти&servaddr.sin_addr.