доброго времени суток, уважаемые. писал программку на Си - что то отдалённо напоминающее хттп клиент отправляет гет запрос и ждет ответа сервера. использует сокеты. Code: #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> void error(char *msg) { perror(msg); exit(0); } int main(int argc, char *argv[]) { int sockfd, portno, n; char str[] = "GET http://127.0.0.1:8088/?identifier=1z2y3z HTTP/1.0\r\n\r\n"; struct sockaddr_in serv_addr; struct hostent *server; char buffer[256]; if (argc < 3) { fprintf(stderr,"usage %s hostname port\n", argv[0]); exit(0); } portno = atoi(argv[2]); sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) error("ERROR opening socket"); server = gethostbyname(argv[1]); if (server == NULL) { fprintf(stderr,"ERROR, no such host\n"); exit(0); } bzero((char *) &serv_addr, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; bcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr, server->h_length); serv_addr.sin_port = htons(portno); if (connect(sockfd,&serv_addr,sizeof(serv_addr)) < 0) error("ERROR connecting"); bzero(buffer,256); n = write(sockfd,str,strlen(str)); if (n < 0) error("ERROR writing to socket"); bzero(buffer,256); n = read(sockfd,buffer,255); if (n < 0) error("ERROR reading from socket"); printf("%s\n",buffer); return 0; } хочу переделать функционал так, чтобы не обрывая соединение, в буфер/переменную (нужное подчеркнуть) попадал ответ сервера. делается это с помощью non-blocking sockets применить наверное к этому Code: n = read(sockfd,buffer,255); след решение выдает ошибку Code: #include <unistd.h> #include <fcntl.h> . . sockfd = socket(AF_INET, SOCK_STREAM, 0); fcntl(sockfd, F_SETFL, O_NONBLOCK); n = read(sockfd,buffer,255); . . ERROR reading from socket: Transport endpoint is not connected Вот тут всё расписано, но у меня не получается сделать нон блокинг сокетс. Если кто сможет переписать программку из листинга 7 из C++ в C буду благодарен. Прошу помощи P.S. сейчас у меня линукс установлен, но юзать прожку буду на мастдае. что то мне думается что на нём работать это не будет и надо использовать winsock api
думаешь правильно.... в мастдае свои механизмы особенно что касается выставление обработчиков WSAAsyncSelect... вызова ф-ций этих обработчиков! есть правда некоторое сходство на блокирующих сокетах!
на блокирующих сокетах тоже можно жить... надо лишь знать что такое потоки и евенты... createThread, createEvent
переписал на winsock с неблокирующими сокетами. доп зависимости в линкере wsock32.lib Ws2_32.lib Code: #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[]= "GET http://127.0.0.1:8088/?identifier=1z2y3z HTTP/1.0\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
ты не понял!!! В Виндоузе неблокирующие сокеты реализуются через WSA**** функции и самую главную из них я указывал твоей программе приходят события FD_READ FD_ACCEPT FD_CLOSE ( FD_WRITE FD_CONNECT ) а обработчики быстро обрабатывают! ... но по моему плохая это идея линуксоиду писать под мастдай на неблокирующих! В этом случае ты должен понимать событийную модель мастдая!
ну проблема то не в этом) неблокирующие я правильно реализовал, смотри Хотя и WSAIoctl тоже хорош, помощнее будет сейчас буду мучать события
2 Kaimi пости по теме, бросать топики близкие по теме ГЛУПО , то у ТС гораздо ближе к истине чум тупые ссылки на МСДН ! У всех есть МСДН посмотрят и без тебя! TC неблокирующие сокеты отдают управление сразу, например recv вернет сразу с нулевым результатом , но гонять recv в цикле ГЛУПО если recv не ждет принятия пакета..... задерживать слипами так же ГЛУПО ... в этом случае проигрыш в производительности блокирующему! Поэтому сервера пишут на асинхронных сокетах учитывающих событийную моlель мастдая,тогда я вполне конкурирую с реализацией в других ОС! Пишу лет 10-ть на асинхронных 8))
Ты вообще умеешь формулировать свои высказывания более менее упорядоченно? Или у тебя психическое расстройство и на базе него проблемы со знаками препинания и ходом мыслей?
TC как ты будешь реализовывать логику обмена? реализация твоя проста.... но логику посложнее ты не сможешь реализовать либо скатишься к СЛИПАМ о которых я писал ВЫШЕ! промоделируй server--------------------------------client 1 пакет >>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<< 2 пакет <<<<<<<<<<<<<<<<<<<< 3 пакет 4 пакет >>>>>>>>>>>>>> детское программирование обычно сводится принял послал принял послал etc но это первый уровень!
я нашел на мсдн'е полный клиент winsock http://msdn.microsoft.com/en-us/library/ms737591(VS.85).aspx сейчас разбираю, буду тестить. Он вроде неблокирующий только не компилится, куча ошибок, хотя в проекте включаю Ws2_32.lib, Mswsock.lib, и Advapi32.lib
Высоконагрузочный для ПРОЦА код годен только для примера! представь скорость с которой будет крутиться последний цикл на recv 8))))))))))))))) то что он заблокирует основную нитку допустим диалогового окна это просто цветочки! ... и будешь сидеть и думать какой нефиговый НЕБЛОКИРУЮЩИЙ сокет 8)) лана не буду больше писать!
а он ведь на Си? или на cpp? Retimiled, может сможешь поправить мой код ? а то я не профи в ентом деле