Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[13.59.230.20] |
|
Страницы: (3) [1] 2 3 все ( Перейти к последнему сообщению ) |
Сообщ.
#1
,
|
|
|
доброго времени суток, уважаемые.
писал программку на Си - что то отдалённо напоминающее хттп клиент должна отправаить запрос и принимть ответы сервера. доп зависимости в линкере wsock32.lib Ws2_32.lib #include <stdio.h> /* for printf(), fprintf() */ #include <winsock.h> /* for socket(),... */ #include <stdlib.h> /* for exit() */ #define RCVBUFSIZE 32 /* Size of receive buffer */ void DieWithError(char *errorMessage){ perror(errorMessage); exit(0); }; /* Error handling function */ void main(int argc, char *argv[]) { int sock; /* Socket descriptor */ struct sockaddr_in echoServAddr; /* Echo server address */ unsigned short echoServPort; /* Echo server port */ char *servIP; /* Server IP address (dotted quad) */ char echoString[]= "identifier=1z2y3z \r\n\r\n"; char echoBuffer[RCVBUFSIZE]; /* Buffer for echo string */ int echoStringLen; /* Length of string to echo */ int bytesRcvd, totalBytesRcvd; /* Bytes read in single recv() and total bytes read */ WSADATA wsaData; /* Structure for WinSock setup communication */ unsigned long nonblocking = 1; if ((argc < 2) || (argc > 3)) /* Test for correct number of arguments */ { fprintf(stderr, "Usage: %s <Server IP> <Echo Port>\n", argv[0]); exit(1); } servIP = argv[1]; /* First arg: server IP address (dotted quad) */ echoServPort = argv[2]; /* Second arg: server port */ if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0) /* Load Winsock 2.0 DLL */ { fprintf(stderr, "WSAStartup() failed"); exit(1); } /* Create a reliable, stream socket using TCP */ if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) DieWithError("socket() failed"); /* Set the socket to nonblocking */ if (ioctlsocket(sock, FIONBIO, &nonblocking) != 0) DieWithError("ioctlsocket() failed"); /* Construct the server address structure */ memset(&echoServAddr, 0, sizeof(echoServAddr)); /* Zero out structure */ echoServAddr.sin_family = AF_INET; /* Internet address family */ echoServAddr.sin_addr.s_addr = inet_addr(servIP); /* Server IP address */ echoServAddr.sin_port = htons(echoServPort); /* Server port */ /* Establish the connection to the echo server */ if (connect(sock, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr)) < 0) DieWithError("connect() failed"); echoStringLen = strlen(echoString); /* Determine input length */ /* Send the string, including the null terminator, to the server */ if (send(sock, echoString, echoStringLen, 0) != echoStringLen) DieWithError("send() sent a different number of bytes than expected"); /* Receive the same string back from the server */ totalBytesRcvd = 0; printf("Received: "); /* Setup to print the echoed string */ while (totalBytesRcvd < echoStringLen) { /* Receive up to the buffer size (minus 1 to leave space for a null terminator) bytes from the sender */ if ((bytesRcvd = recv(sock, echoBuffer, RCVBUFSIZE - 1, 0)) <= 0) DieWithError("recv() failed or connection closed prematurely"); totalBytesRcvd += bytesRcvd; /* Keep tally of total bytes */ echoBuffer[bytesRcvd] = '\0'; /* Add \0 so printf knows where to stop */ printf("%s", echoBuffer); /* Print the echo buffer */ } printf("\n"); /* Print a final linefeed */ closesocket(sock); WSACleanup(); /* Cleanup Winsock */ exit(0); } при коннекте "program.exe host port" ошибка соединения, почему не понимаю connect () failed: no error прошу помощи в разъяснении |
Сообщ.
#2
,
|
|
|
Цитата If no error occurs, connect returns zero. Otherwise, it returns SOCKET_ERROR, and a specific error code can be retrieved by calling WSAGetLastError. On a blocking socket, the return value indicates success or failure of the connection attempt. With a nonblocking socket, the connection attempt cannot be completed immediately. In this case, connect will return SOCKET_ERROR, and WSAGetLastError will return WSAEWOULDBLOCK. In this case, there are three possible scenarios: Use the select function to determine the completion of the connection request by checking to see if the socket is writeable. If the application is using WSAAsyncSelect to indicate interest in connection events, then the application will receive an FD_CONNECT notification indicating that the connect operation is complete (successfully or not). If the application is using WSAEventSelect to indicate interest in connection events, then the associated event object will be signaled indicating that the connect operation is complete (successfully or not). Короче, в неблокирующем режиме, он может сразу не подключиться, возвращая WSAEWOULDBLOCK. Всго лишь нужно подождать, либо использовать select для того, чтобы убедиться в завершенности операции. |
Сообщ.
#3
,
|
|
|
в смысле подождать
|
Сообщ.
#4
,
|
|
|
Если программа несерьезная, можно вставить sleep после connect, когда - нибудь соединение да произойдет, если сервер доступен.
Но лучше так не делать и использовать WSAAsyncSelect c флагом события FD_CONNECT. |
Сообщ.
#5
,
|
|
|
поменял
echoServPort = argv[2]; на echoServPort = atoi(argv[2]); .. #include <unistd.h> .. .. /* Create a reliable, stream socket using TCP */ if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) ) < 0) DieWithError("socket() failed"); sleep(5); /* Set the socket to nonblocking */ if (ioctlsocket(sock, FIONBIO, &nonblocking) != 0) DieWithError("ioctlsocket() failed"); .. .. Не удается открыть файл include: unistd.h: No such file or directory Этж только под никсами... а на мастдае как? и еще: как с WSAAsyncSelect сделать? можно на примере моей проги показать? Или киньте ссылку, где подробно расписано о WSAAsyncSelect для Си |
Сообщ.
#6
,
|
|
|
подправил. теперь c select. ждет 2.5 секунды и выходит
Программа "[2312] у3к6.exe: Машинный код" завершилась с кодом 0 (0x0). #include <stdio.h> /* for printf(), fprintf() */ #include <winsock.h> /* for socket(),... */ #include <stdlib.h> /* for exit() */ #include <time.h> #include <sys/types.h> #define RCVBUFSIZE 32 /* Size of receive buffer */ void DieWithError(char *errorMessage){ perror(errorMessage); exit(0); }; /* Error handling function */ void main(int argc, char *argv[]) { int sock, rc, read_fds, echoServPort; struct sockaddr_in echoServAddr; // unsigned short echoServPort; char *servIP; char echoString[]= "identifier=1z2y3z \r\n\r\n"; char echoBuffer[RCVBUFSIZE]; /* Buffer for echo string */ int echoStringLen; /* Length of string to echo */ int bytesRcvd, totalBytesRcvd; /* Bytes read in single recv() and total bytes read */ WSADATA wsaData; /* Structure for WinSock setup communication */ unsigned long nonblocking = 1; struct timeval tv; fd_set readfds; tv.tv_sec = 2; tv.tv_usec = 500000; servIP = argv[1]; /* First arg: server IP address (dotted quad) */ // echoServPort = atoi(argv[2]); /* Use given port, if any */ echoServPort = 8088; if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0) /* Load Winsock 2.0 DLL */ { fprintf(stderr, "WSAStartup() failed"); exit(1); } /* Create a reliable, stream socket using TCP */ if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) ) < 0) DieWithError("socket() failed"); /* Set the socket to nonblocking */ if (ioctlsocket(sock, FIONBIO, &nonblocking) != 0) DieWithError("ioctlsocket() failed"); /* Construct the server address structure */ memset(&echoServAddr, 0, sizeof(echoServAddr)); /* Zero out structure */ echoServAddr.sin_family = AF_INET; /* Internet address family */ echoServAddr.sin_addr.s_addr = inet_addr(servIP); /* Server IP address */ echoServAddr.sin_port = htons(echoServPort); /* Server port */ FD_ZERO(&readfds); FD_SET(sock, &readfds); rc = select(sock, &readfds, NULL, NULL, &tv); if((rc == 1) && (FD_ISSET(sock, &read_fds))) { /* Establish the connection to the echo server */ if (connect(sock, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr)) < 0) DieWithError("connect() failed"); echoStringLen = strlen(echoString); /* Determine input length */ /* Send the string, including the null terminator, to the server */ if (send(sock, echoString, echoStringLen, 0) != echoStringLen) DieWithError("send() sent a different number of bytes than expected"); /* Receive the same string back from the server */ totalBytesRcvd = 0; printf("Received: "); /* Setup to print the echoed string */ while (totalBytesRcvd < echoStringLen) { /* Receive up to the buffer size (minus 1 to leave space for a null terminator) bytes from the sender */ if ((bytesRcvd = recv(sock, echoBuffer, RCVBUFSIZE - 1, 0)) <= 0) DieWithError("recv() failed or connection closed prematurely"); totalBytesRcvd += bytesRcvd; /* Keep tally of total bytes */ echoBuffer[bytesRcvd] = '\0'; /* Add \0 so printf knows where to stop */ printf("%s", echoBuffer); /* Print the echo buffer */ } } printf("\n"); /* Print a final linefeed */ closesocket(sock); WSACleanup(); /* Cleanup Winsock */ exit(0); } |
Сообщ.
#7
,
|
|
|
Ты бы поспал
В твоем случае rc = select(sock, &readfds, NULL, NULL, &tv); ожидает, когда в сокет придут данные, сокет, который даже не подключен (connect ниже). select нужно использовать не для ожидания того, когда он будет готов для чтения, а для ожидания того, когда он будет готов для записи. А это другой параметр. удачи! |
Сообщ.
#8
,
|
|
|
таже фигня
#include <stdio.h> /* for printf(), fprintf() */ #include <winsock.h> /* for socket(),... */ #include <stdlib.h> /* for exit() */ #include <time.h> #include <sys/types.h> #define RCVBUFSIZE 32 /* Size of receive buffer */ void DieWithError(char *errorMessage){ perror(errorMessage); exit(0); }; /* Error handling function */ void main(int argc, char *argv[]) { int sock, rc; /* Socket descriptor */ struct sockaddr_in echoServAddr; /* Echo server address */ unsigned short echoServPort; /* Echo server port */ char *servIP; /* Server IP address (dotted quad) */ char echoString[]= "identifier=1z2y3z \r\n\r\n"; char echoBuffer[RCVBUFSIZE]; /* Buffer for echo string */ int echoStringLen; /* Length of string to echo */ int bytesRcvd, totalBytesRcvd; /* Bytes read in single recv() and total bytes read */ WSADATA wsaData; /* Structure for WinSock setup communication */ unsigned long nonblocking = 1; fd_set writefds; struct timeval tv; tv.tv_sec = 2; tv.tv_usec = 500000; servIP = argv[1]; /* First arg: server IP address (dotted quad) */ echoServPort = atoi(argv[2]); /* Use given port, if any */ if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0) /* Load Winsock 2.0 DLL */ { fprintf(stderr, "WSAStartup() failed"); exit(1); } /* Create a reliable, stream socket using TCP */ if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) ) < 0) DieWithError("socket() failed"); /* Set the socket to nonblocking */ if (ioctlsocket(sock, FIONBIO, &nonblocking) != 0) DieWithError("ioctlsocket() failed"); /* Construct the server address structure */ memset(&echoServAddr, 0, sizeof(echoServAddr)); /* Zero out structure */ echoServAddr.sin_family = AF_INET; /* Internet address family */ echoServAddr.sin_addr.s_addr = inet_addr(servIP); /* Server IP address */ echoServAddr.sin_port = htons(echoServPort); /* Server port */ FD_ZERO(&writefds); FD_SET(sock, &writefds); rc = select(sock, NULL, &writefds, NULL, &tv); if((rc == 1) && (FD_ISSET(sock, &writefds))) { /* Establish the connection to the echo server */ if (connect(sock, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr)) < 0) DieWithError("connect() failed"); echoStringLen = strlen(echoString); /* Determine input length */ /* Send the string, including the null terminator, to the server */ if (send(sock, echoString, echoStringLen, 0) != echoStringLen) DieWithError("send() sent a different number of bytes than expected"); /* Receive the same string back from the server */ totalBytesRcvd = 0; printf("Received: "); /* Setup to print the echoed string */ while (totalBytesRcvd < echoStringLen) { /* Receive up to the buffer size (minus 1 to leave space for a null terminator) bytes from the sender */ if ((bytesRcvd = recv(sock, echoBuffer, RCVBUFSIZE - 1, 0)) <= 0) DieWithError("recv() failed or connection closed prematurely"); totalBytesRcvd += bytesRcvd; /* Keep tally of total bytes */ echoBuffer[bytesRcvd] = '\0'; /* Add \0 so printf knows where to stop */ printf("%s", echoBuffer); /* Print the echo buffer */ } } printf("\n"); /* Print a final linefeed */ closesocket(sock); WSACleanup(); /* Cleanup Winsock */ exit(0); } |
Сообщ.
#9
,
|
|
|
Цитата sign63 @ ... ... while (totalBytesRcvd < echoStringLen) { .... if ((bytesRcvd = recv(sock, echoBuffer, RCVBUFSIZE - 1, 0)) <= 0) ... totalBytesRcvd += bytesRcvd; /* Keep tally of total bytes */ echoBuffer[bytesRcvd] = '\0'; /* Add \0 so printf knows where to stop */ .. } ... не понятна следующая логика. 1) цикл на общую длину. 2) идёт перезатирка ранее принятых данных. так вам что нуна то? Приём по кусочкам на которые раздробил данные нижний уровень(или вы в передатчике) или приём полной длины эхо строки? это не будет понятно пока у вас строка маленькая, работаете не в боевой сети и на нагрузках типа хэлохты мир. увеличьте строку скажем до пары метров. удачи вам (круглый) |
Сообщ.
#10
,
|
|
|
Цитата kolobok0 @ Цитата sign63 @ ... ... while (totalBytesRcvd < echoStringLen) { .... if ((bytesRcvd = recv(sock, echoBuffer, RCVBUFSIZE - 1, 0)) <= 0) ... totalBytesRcvd += bytesRcvd; /* Keep tally of total bytes */ echoBuffer[bytesRcvd] = '\0'; /* Add \0 so printf knows where to stop */ .. } ... не понятна следующая логика. 1) цикл на общую длину. 2) идёт перезатирка ранее принятых данных. так вам что нуна то? Приём по кусочкам на которые раздробил данные нижний уровень(или вы в передатчике) или приём полной длины эхо строки? это не будет понятно пока у вас строка маленькая, работаете не в боевой сети и на нагрузках типа хэлохты мир. увеличьте строку скажем до пары метров. удачи вам (круглый) над приемом данных еще подумаю, но проблема сейчас пока что в коннекте к серверу, надо её сначало решить |
Сообщ.
#11
,
|
|
|
Цитата sign63 @ доп зависимости в линкере wsock32.lib Ws2_32.lib Зачем линкуете сразу две библиотеки? Вы работаете с версией винсок 2.0 (WSAStartup(MAKEWORD(2, 0), &wsaData) - потому только Ws2_32.lib и еще - winsock2.h |
Сообщ.
#12
,
|
|
|
Цитата Oleg2004 @ Цитата sign63 @ доп зависимости в линкере wsock32.lib Ws2_32.lib Зачем линкуете сразу две библиотеки? Вы работаете с версией винсок 2.0 (WSAStartup(MAKEWORD(2, 0), &wsaData) - потому только Ws2_32.lib и еще - winsock2.h просто были траблы на ранней части написания, в каком то из мануалов вымсмотрел. убрал лишнюю wsock32.lib, поправил winsock.h на winsock2.h нашёл WWinsock Interface Library for C/C++ 3.1 там куча примеров, есть то что мне надо async.c но не компилируется, зараза в visual studio. по идее такие как эти проекты (стоимость 130$ на офф сайте) должны сразу без проблем компилится Цитата Компиляция... ASYNC.C z:\wil4c\ASYNC.C(69) : warning C4133: функция: несовместимые типы - из 'LPSTR' в 'LPWSTR' z:\wil4c\ASYNC.C(69) : warning C4133: функция: несовместимые типы - из 'char [17]' в 'LPCWSTR' z:\wil4c\ASYNC.C(95) : warning C4133: функция: несовместимые типы - из 'LPSTR' в 'LPWSTR' z:\wil4c\ASYNC.C(95) : warning C4133: функция: несовместимые типы - из 'char [29]' в 'LPCWSTR' z:\wil4c\ASYNC.C(146) : warning C4133: функция: несовместимые типы - из 'LPSTR' в 'LPWSTR' z:\wil4c\ASYNC.C(146) : warning C4133: функция: несовместимые типы - из 'char [17]' в 'LPCWSTR' z:\wil4c\ASYNC.C(167) : warning C4133: функция: несовместимые типы - из 'LPSTR' в 'LPWSTR' z:\wil4c\ASYNC.C(167) : warning C4133: функция: несовместимые типы - из 'char [25]' в 'LPCWSTR' z:\wil4c\ASYNC.C(176) : warning C4133: функция: несовместимые типы - из 'LPSTR' в 'LPCWSTR' z:\wil4c\ASYNC.C(192) : warning C4133: функция: несовместимые типы - из 'LPSTR' в 'LPWSTR' z:\wil4c\ASYNC.C(192) : warning C4133: функция: несовместимые типы - из 'char [30]' в 'LPCWSTR' z:\wil4c\ASYNC.C(202) : warning C4133: функция: несовместимые типы - из 'LPSTR' в 'LPCWSTR' Компоновка... ASYNC.obj : error LNK2001: неразрешенный внешний символ "__imp__wilTcpSocket@0" ASYNC.obj : error LNK2001: неразрешенный внешний символ "__imp__wilMakeAddr@4" ASYNC.obj : error LNK2001: неразрешенный внешний символ "__imp__wilErrorText@12" ASYNC.obj : error LNK2001: неразрешенный внешний символ "__imp__wilReadLine@12" ASYNC.obj : error LNK2001: неразрешенный внешний символ "__imp__wilGetHostAddr@8" ASYNC.obj : error LNK2001: неразрешенный внешний символ "_DisplayLine" ASYNC.obj : error LNK2001: неразрешенный внешний символ "__imp__wilIsDotted@4" ASYNC.obj : error LNK2001: неразрешенный внешний символ "__imp__wilMakeDotted@12" ASYNC.obj : error LNK2001: неразрешенный внешний символ "__imp__wilWriteLine@8" ASYNC.obj : error LNK2001: неразрешенный внешний символ "_StringCopy" ASYNC.obj : error LNK2001: неразрешенный внешний символ "_DisplayString" ASYNC.obj : error LNK2001: неразрешенный внешний символ "__imp__wilConnect@12" ASYNC.obj : error LNK2001: неразрешенный внешний символ "__imp__wilParseDecimal@4" ASYNC.obj : error LNK2001: неразрешенный внешний символ "__imp__wilWaitLine@20" ASYNC.obj : error LNK2001: неразрешенный внешний символ "__imp__wilAwaitEvent@16" MSVCRT.lib(crtexe.obj) : error LNK2001: неразрешенный внешний символ "_main" а miracle C ругается только на Цитата wil.h: line 71: Parse Error, expecting `','' or `SEP' 'SOCKET FAR' aborting compile |
Сообщ.
#13
,
|
|
|
Сообщ.
#14
,
|
|
|
Цитата sign63 @ а значения sin_port, echoServAddr.sin_port разве должны быть такими? Они преобразованы ы порядок сети - а выводятся в порядке хоста. |
Сообщ.
#15
,
|
|
|
как сказал мне один форумчанин:
Цитата в данной ситуации позволяет дождаться, когда будет закончено выполнение предыдущей операции. Пока коннект с сервером не установлен, ни о какой отправке данных речи быть не может, поэтому ждём:select (sock, NULL, &writefds, NULL, &tv); потом говорим write, и хотим прочитать ответ. Но пока ответ не пришёл, читать бессмысленно. Поэтому select (sock, &readfds, NULL, NULL, &tv); и только потом read. |