From mboxrd@z Thu Jan 1 00:00:00 1970 From: "Robert A. Mackie" To: cygwin@sourceware.cygnus.com Cc: robert_mackie@mail.com Subject: posix style DGRAM sockets with cygwin.dll Date: Mon, 23 Aug 1999 23:39:00 -0000 Message-id: <37C23EE9.92525BD@mail.com> X-SW-Source: 1999-08/msg00588.html I'm trying to get a very simple UDP example ported to cygwin as a starting point for some real code I expect to develop. Everything compiles and links, but the sockets don't communicate. When built for unix the same code works fine. (unless I've introduced some small bug trying to get it to work under cygwin.) I notice I'm not the first to say something like this. The last person was using the -no-cygwin option and was told to call WSAStartup. I read as much documentation as I could find. It looked to me like that was not necessary when using the posix calls, rather than the winsock calls. (Maybe I'm wrong ?) If I do need to initialize winsock explicitly, could you help me with a couple of details? The only place that I see WSAStartup and WSACleanup defined is in . This file seems to be set up for an MSC compiler, and includes a bunch of other similar headers. When I include any of them and the standard headers I'm used to, I get all sorts of re-definition collisions between the headers. When I include them without the standard headers, things like strerror aren't defined. The specific problem I'm having is that the datagrams never get through to the receiver. I have an alternate client and server that I tossed together in Java to make sure my system was working (DNS et al.), and while they work, they show me that neither the client nor the server developed using cygwin appear to actually use the network. For example, I can bind the Java server to port 7000, and then launch the server developed under cygwin on port 7000, and it doesn't complain. Clearly, I'm missing something fundamental. Thanks for any help you can provide. Rob Mackie. Here is the code; it's a dirty adaption of code found in Stephen's book on network programming: server.cc: #include "DataGramUtility.hh" int main(int c, char* argv[]) { return DataGramUtility::server(c, argv); } client.cc: #include "DataGramUtility.hh" int main(int c, char* argv[]) { return DataGramUtility::client(c, argv); } DataGramUtility.hh: #if( ! defined(DATA_GRAM_UTILITY) ) #define DATA_GRAM_UTILITY #include #include #include #include class DataGramUtility { public: static int client(int argc, char* argv[]); static int server(int argc, char* argv[]); private: static int initialize(); static int cleanup(); static int serverLoop( int sockfd , struct sockaddr* pcli_addr , int maxclilen); static int clientLoop( FILE* fp , int sockfd , struct sockaddr* pserv_addr , int servlen); }; DataGramUtility.cc: #include "DataGramUtility.hh" #include #include #include #include #include #include #include #define MAXMESG 2048 #define LOCATION __FILE__, __LINE__ void printError(const char* file, int line) { printf("%s:%d - %s\n" , file, line, strerror( errno )); } int DataGramUtility::serverLoop(int sockfd , struct sockaddr* pcli_addr , int maxClientLength) { int byteCount; int clientLength; char message[MAXMESG]; while( true ) { clientLength = maxClientLength; printf("waiting to recieve\n"); byteCount = recvfrom(sockfd, message, MAXMESG, 0, pcli_addr, &clientLength); if( byteCount < 0 ) { printf("DataGramUtility::serverLoop - recvfrom error: %d\n" , byteCount); printError(LOCATION); } message[byteCount] = '\0'; printf("received: %s\n", message); if( sendto( sockfd , message , byteCount , 0, pcli_addr, clientLength) != byteCount) { printf("DataGramUtility::serverLoop - sendto error\n"); printError(LOCATION); } printf("echo'd back to sender\n"); } return 0; } #define MAXLINE 512 int DataGramUtility::clientLoop( FILE* fp , int sockfd , struct sockaddr* pserv_addr , int serverLength) { int byteCount; char sendline[MAXLINE]; // char recvline[MAXLINE+1]; printf("Ready to send\n"); while( fgets(sendline, MAXLINE, fp) != NULL ) { printf("read: %s\n", sendline); byteCount = strlen(sendline); if( sendto( sockfd , sendline , byteCount , 0, pserv_addr, serverLength) != byteCount) { printf("DataGramUtility::client - sendto error on socket\n"); printError(LOCATION); } printf("sent\n"); #if 0 byteCount = recvfrom(sockfd , recvline , MAXLINE , 0 , (struct sockaddr*)0 , (int*) 0 ); if( byteCount < 0 ) { printf("DataGramUtility::client - recvfrom error on socket\n"); printError(LOCATION); } printf("received\n"); recvline[byteCount] = 0; fputs(recvline, stdout); #endif } return 0; } int DataGramUtility::client(int argc, char* argv[]) { if(DataGramUtility::initialize() == -1) { printf("Couldn't initialize winsock\n"); return -1; } int sockfd; struct sockaddr_in client_address; struct sockaddr_in server_address; if( argc < 3 ) { printf("Usage: %s hostip port\n", argv[0]); return -1; } const char* SERVER_HOST_ADDRESS = argv[1]; const int SERVER_UDP_PORT = atoi(argv[2]); bzero((char*)&server_address, sizeof(server_address)); server_address.sin_family = AF_INET; server_address.sin_addr.s_addr = inet_addr(SERVER_HOST_ADDRESS); server_address.sin_port = htonl(SERVER_UDP_PORT); if( server_address.sin_addr.s_addr == htonl(0x7F000001) ) { printf("Address is local host.\n"); } printf("IP: "); for( int i = 0; i<4; i++ ) { printf( "%d.", ((unsigned char*)(&server_address.sin_addr.s_addr))[i] ); } if( (sockfd = socket(AF_INET, SOCK_DGRAM, 0 )) < 0 ) { printf("DataGramUtility::client - can't open datagram socket\n"); printError(LOCATION); return -1; } bzero((char*)&client_address, sizeof(client_address)); client_address.sin_family = AF_INET; client_address.sin_addr.s_addr = htonl(INADDR_ANY); client_address.sin_port = htonl(0); if( bind( sockfd , (struct sockaddr*)&client_address , sizeof(client_address)) < 0 ) { printf("DataGramUtility::client - can't bind local address\n"); printError(LOCATION); return -1; } DataGramUtility::clientLoop( stdin , sockfd , (struct sockaddr*)&server_address , sizeof(server_address)); close(sockfd); DataGramUtility::cleanup(); return 0; } int DataGramUtility::server(int argc, char* argv[]) { if(DataGramUtility::initialize() == -1) { printf("Couldn't initialize winsock\n"); return -1; } int sockfd; struct sockaddr_in server_address; struct sockaddr_in client_address; if( argc < 2 ) { printf("Usage: %s port\n", argv[0]); return -1; } const int SERVER_UDP_PORT = atoi(argv[1]); if( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) { printf("DataGramUtility::server - can't open datagram socket\n"); printError(LOCATION); return -1; } bzero((char*)&server_address, sizeof(server_address)); server_address.sin_family = AF_INET; server_address.sin_addr.s_addr = htonl(INADDR_ANY); server_address.sin_port = htonl(SERVER_UDP_PORT); if( bind( sockfd , (struct sockaddr*) &server_address , sizeof(server_address)) < 0 ) { printf("DataGramUtility::server - can't bind local address\n"); printError(LOCATION); return -1; } DataGramUtility::serverLoop( sockfd , (struct sockaddr*)&client_address , sizeof(client_address)); DataGramUtility::cleanup(); return 0; } int DataGramUtility::initialize() { #if 0 WSADATA WSAData; if (WSAStartup(0x0101, &WSAData)) { printf("WSAStartup failed (%d)\n",WSAGetLastError()); return -1; } #endif return 0; } int DataGramUtility::cleanup() { #if 0 WSACleanup(); #endif } From mboxrd@z Thu Jan 1 00:00:00 1970 From: "Robert A. Mackie" To: cygwin@sourceware.cygnus.com Cc: robert_mackie@mail.com Subject: posix style DGRAM sockets with cygwin.dll Date: Tue, 31 Aug 1999 23:49:00 -0000 Message-ID: <37C23EE9.92525BD@mail.com> X-SW-Source: 1999-08n/msg00588.html Message-ID: <19990831234900.ajwf-tIna6B1E-XBCbuiDaSbpdj6lZu86pUr_hR_0-U@z> I'm trying to get a very simple UDP example ported to cygwin as a starting point for some real code I expect to develop. Everything compiles and links, but the sockets don't communicate. When built for unix the same code works fine. (unless I've introduced some small bug trying to get it to work under cygwin.) I notice I'm not the first to say something like this. The last person was using the -no-cygwin option and was told to call WSAStartup. I read as much documentation as I could find. It looked to me like that was not necessary when using the posix calls, rather than the winsock calls. (Maybe I'm wrong ?) If I do need to initialize winsock explicitly, could you help me with a couple of details? The only place that I see WSAStartup and WSACleanup defined is in . This file seems to be set up for an MSC compiler, and includes a bunch of other similar headers. When I include any of them and the standard headers I'm used to, I get all sorts of re-definition collisions between the headers. When I include them without the standard headers, things like strerror aren't defined. The specific problem I'm having is that the datagrams never get through to the receiver. I have an alternate client and server that I tossed together in Java to make sure my system was working (DNS et al.), and while they work, they show me that neither the client nor the server developed using cygwin appear to actually use the network. For example, I can bind the Java server to port 7000, and then launch the server developed under cygwin on port 7000, and it doesn't complain. Clearly, I'm missing something fundamental. Thanks for any help you can provide. Rob Mackie. Here is the code; it's a dirty adaption of code found in Stephen's book on network programming: server.cc: #include "DataGramUtility.hh" int main(int c, char* argv[]) { return DataGramUtility::server(c, argv); } client.cc: #include "DataGramUtility.hh" int main(int c, char* argv[]) { return DataGramUtility::client(c, argv); } DataGramUtility.hh: #if( ! defined(DATA_GRAM_UTILITY) ) #define DATA_GRAM_UTILITY #include #include #include #include class DataGramUtility { public: static int client(int argc, char* argv[]); static int server(int argc, char* argv[]); private: static int initialize(); static int cleanup(); static int serverLoop( int sockfd , struct sockaddr* pcli_addr , int maxclilen); static int clientLoop( FILE* fp , int sockfd , struct sockaddr* pserv_addr , int servlen); }; DataGramUtility.cc: #include "DataGramUtility.hh" #include #include #include #include #include #include #include #define MAXMESG 2048 #define LOCATION __FILE__, __LINE__ void printError(const char* file, int line) { printf("%s:%d - %s\n" , file, line, strerror( errno )); } int DataGramUtility::serverLoop(int sockfd , struct sockaddr* pcli_addr , int maxClientLength) { int byteCount; int clientLength; char message[MAXMESG]; while( true ) { clientLength = maxClientLength; printf("waiting to recieve\n"); byteCount = recvfrom(sockfd, message, MAXMESG, 0, pcli_addr, &clientLength); if( byteCount < 0 ) { printf("DataGramUtility::serverLoop - recvfrom error: %d\n" , byteCount); printError(LOCATION); } message[byteCount] = '\0'; printf("received: %s\n", message); if( sendto( sockfd , message , byteCount , 0, pcli_addr, clientLength) != byteCount) { printf("DataGramUtility::serverLoop - sendto error\n"); printError(LOCATION); } printf("echo'd back to sender\n"); } return 0; } #define MAXLINE 512 int DataGramUtility::clientLoop( FILE* fp , int sockfd , struct sockaddr* pserv_addr , int serverLength) { int byteCount; char sendline[MAXLINE]; // char recvline[MAXLINE+1]; printf("Ready to send\n"); while( fgets(sendline, MAXLINE, fp) != NULL ) { printf("read: %s\n", sendline); byteCount = strlen(sendline); if( sendto( sockfd , sendline , byteCount , 0, pserv_addr, serverLength) != byteCount) { printf("DataGramUtility::client - sendto error on socket\n"); printError(LOCATION); } printf("sent\n"); #if 0 byteCount = recvfrom(sockfd , recvline , MAXLINE , 0 , (struct sockaddr*)0 , (int*) 0 ); if( byteCount < 0 ) { printf("DataGramUtility::client - recvfrom error on socket\n"); printError(LOCATION); } printf("received\n"); recvline[byteCount] = 0; fputs(recvline, stdout); #endif } return 0; } int DataGramUtility::client(int argc, char* argv[]) { if(DataGramUtility::initialize() == -1) { printf("Couldn't initialize winsock\n"); return -1; } int sockfd; struct sockaddr_in client_address; struct sockaddr_in server_address; if( argc < 3 ) { printf("Usage: %s hostip port\n", argv[0]); return -1; } const char* SERVER_HOST_ADDRESS = argv[1]; const int SERVER_UDP_PORT = atoi(argv[2]); bzero((char*)&server_address, sizeof(server_address)); server_address.sin_family = AF_INET; server_address.sin_addr.s_addr = inet_addr(SERVER_HOST_ADDRESS); server_address.sin_port = htonl(SERVER_UDP_PORT); if( server_address.sin_addr.s_addr == htonl(0x7F000001) ) { printf("Address is local host.\n"); } printf("IP: "); for( int i = 0; i<4; i++ ) { printf( "%d.", ((unsigned char*)(&server_address.sin_addr.s_addr))[i] ); } if( (sockfd = socket(AF_INET, SOCK_DGRAM, 0 )) < 0 ) { printf("DataGramUtility::client - can't open datagram socket\n"); printError(LOCATION); return -1; } bzero((char*)&client_address, sizeof(client_address)); client_address.sin_family = AF_INET; client_address.sin_addr.s_addr = htonl(INADDR_ANY); client_address.sin_port = htonl(0); if( bind( sockfd , (struct sockaddr*)&client_address , sizeof(client_address)) < 0 ) { printf("DataGramUtility::client - can't bind local address\n"); printError(LOCATION); return -1; } DataGramUtility::clientLoop( stdin , sockfd , (struct sockaddr*)&server_address , sizeof(server_address)); close(sockfd); DataGramUtility::cleanup(); return 0; } int DataGramUtility::server(int argc, char* argv[]) { if(DataGramUtility::initialize() == -1) { printf("Couldn't initialize winsock\n"); return -1; } int sockfd; struct sockaddr_in server_address; struct sockaddr_in client_address; if( argc < 2 ) { printf("Usage: %s port\n", argv[0]); return -1; } const int SERVER_UDP_PORT = atoi(argv[1]); if( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) { printf("DataGramUtility::server - can't open datagram socket\n"); printError(LOCATION); return -1; } bzero((char*)&server_address, sizeof(server_address)); server_address.sin_family = AF_INET; server_address.sin_addr.s_addr = htonl(INADDR_ANY); server_address.sin_port = htonl(SERVER_UDP_PORT); if( bind( sockfd , (struct sockaddr*) &server_address , sizeof(server_address)) < 0 ) { printf("DataGramUtility::server - can't bind local address\n"); printError(LOCATION); return -1; } DataGramUtility::serverLoop( sockfd , (struct sockaddr*)&client_address , sizeof(client_address)); DataGramUtility::cleanup(); return 0; } int DataGramUtility::initialize() { #if 0 WSADATA WSAData; if (WSAStartup(0x0101, &WSAData)) { printf("WSAStartup failed (%d)\n",WSAGetLastError()); return -1; } #endif return 0; } int DataGramUtility::cleanup() { #if 0 WSACleanup(); #endif }