#include #include #include #include #include #define sleep(x) Sleep(x*1000) void printerr(int); void do_initialization(void); void do_exit(int); WINAPI server_thread(int); WINAPI client_thread(int); void do_exit(int status) { WSACleanup(); exit(status); } void do_initialization(void) { WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested=MAKEWORD(1, 1); err=WSAStartup(wVersionRequested, &wsaData); if (err) { printerr(err); fprintf(stderr, " at WSAStartup() call\n"); exit(EXIT_FAILURE); } if (LOBYTE(wsaData.wVersion)!=1 || HIBYTE(wsaData.wVersion)!=1) { fprintf(stderr, "winsock 1.1 not supported\n"); WSACleanup(); exit(EXIT_FAILURE); } } void printerr(int err) { switch (err) { case WSAEINTR: fprintf(stderr, "blocking call canceled"); break; case WSAEBADF: fprintf(stderr, "WSAEBADF"); break; case WSAEACCES: fprintf(stderr, "WSAEACCES"); break; case WSAEFAULT: fprintf(stderr, "buffer too small"); break; case WSAEINVAL: fprintf(stderr, "DLL doesn't support this winsock version, " "socket already bound to an address,\n" "or socket not bound with bind()"); break; case WSAEMFILE: fprintf(stderr, "no more file descriptors available"); break; case WSAEWOULDBLOCK: fprintf(stderr, "operation would block"); break; case WSAEINPROGRESS: fprintf(stderr, "blocking call in progress"); break; case WSAEALREADY: fprintf(stderr, "WSAEALREADY"); break; case WSAENOTSOCK: fprintf(stderr, "descriptor is not a socket"); break; case WSAEDESTADDRREQ: fprintf(stderr, "WSAEDESTADDRREQ"); break; case WSAEMSGSIZE: fprintf(stderr, "datagram too large for buffer"); break; case WSAEPROTOTYPE: fprintf(stderr, "specified protocol is the wrong type for this socket"); break; case WSAENOPROTOOPT: fprintf(stderr, "WSAENOPROTOOPT"); break; case WSAEPROTONOSUPPORT: fprintf(stderr, "specified protocol not supported"); break; case WSAESOCKTNOSUPPORT: fprintf(stderr, "socket type not supported in address family"); break; case WSAEOPNOTSUPP: fprintf(stderr, "operation not supported"); break; case WSAEPFNOSUPPORT: fprintf(stderr, "WSAEPFNOSUPPORT"); break; case WSAEAFNOSUPPORT: fprintf(stderr, "address family not supported"); break; case WSAEADDRINUSE: fprintf(stderr, "address in use"); break; case WSAEADDRNOTAVAIL: fprintf(stderr, "WSAEADDRNOTAVAIL"); break; case WSAENETDOWN: fprintf(stderr, "network down"); break; case WSAENETUNREACH: fprintf(stderr, "WSAENETUNREACH"); break; case WSAENETRESET: fprintf(stderr, "WSAENETRESET"); break; case WSAECONNABORTED: fprintf(stderr, "connection aborted"); break; case WSAECONNRESET: fprintf(stderr, "connection reset by peer"); break; case WSAENOBUFS: fprintf(stderr, "no buffer space available"); break; case WSAEISCONN: fprintf(stderr, "WSAEISCONN"); break; case WSAENOTCONN: fprintf(stderr, "socket not connected"); break; case WSAESHUTDOWN: fprintf(stderr, "socket has been shut down"); break; case WSAETOOMANYREFS: fprintf(stderr, "WSAETOOMANYREFS"); break; case WSAETIMEDOUT: fprintf(stderr, "WSAETIMEDOUT"); break; case WSAECONNREFUSED: fprintf(stderr, "WSAECONNREFUSED"); break; case WSAELOOP: fprintf(stderr, "WSAELOOP"); break; case WSAENAMETOOLONG: fprintf(stderr, "WSAENAMETOOLONG"); break; case WSAEHOSTDOWN: fprintf(stderr, "WSAEHOSTDOWN"); break; case WSAEHOSTUNREACH: fprintf(stderr, "WSAEHOSTUNREACH"); break; case WSAENOTEMPTY: fprintf(stderr, "WSAEHOSTUNREACH"); break; case WSAEPROCLIM: fprintf(stderr, "WSAEPROCLIM"); break; case WSAEUSERS: fprintf(stderr, "WSAEUSERS"); break; case WSAEDQUOT: fprintf(stderr, "WSAEDQUOT"); break; case WSAESTALE: fprintf(stderr, "WSAESTALE"); break; case WSAEREMOTE: fprintf(stderr, "WSAEREMOTE"); break; case WSAEDISCON: fprintf(stderr, "WSAEDISCON"); break; case WSASYSNOTREADY: fprintf(stderr, "network not ready"); break; case WSAVERNOTSUPPORTED: fprintf(stderr, "incorrect winsock version"); break; case WSANOTINITIALISED: fprintf(stderr, "winsock not initialized"); break; case WSAHOST_NOT_FOUND: fprintf(stderr, "WSAHOST_NOT_FOUND"); break; case WSATRY_AGAIN: fprintf(stderr, "WSATRY_AGAIN"); break; case WSANO_RECOVERY: fprintf(stderr, "unrecoverable error"); break; case WSANO_DATA: fprintf(stderr, "no data record of requested type"); break; default: fprintf(stderr, "unknown error"); } } WINAPI server_thread(int param) { struct protoent *udp; SOCKET fd; struct sockaddr_in sin; int bytes; char buf[1024]; struct sockaddr from; int fromlen; HANDLE handle; udp=getprotobyname("udp"); if (udp==NULL) { printerr(WSAGetLastError()); fprintf(stderr, " at getprotobyname() call\n"); do_exit(EXIT_FAILURE); } fd=socket(AF_INET, SOCK_DGRAM, udp->p_proto); if (fd==INVALID_SOCKET) { printerr(WSAGetLastError()); fprintf(stderr, " at socket() call\n"); do_exit(EXIT_FAILURE); } memset(&sin, 0, sizeof(sin)); sin.sin_family=AF_INET; sin.sin_port=htons(9999); sin.sin_addr.s_addr=INADDR_ANY; if (bind(fd, (struct sockaddr *)&sin, sizeof(sin))==SOCKET_ERROR) { printerr(WSAGetLastError()); fprintf(stderr, " at bind() call\n"); do_exit(EXIT_FAILURE); } memset(&buf, 0, 1024); fromlen=sizeof(from); handle=OpenEvent(EVENT_MODIFY_STATE|SYNCHRONIZE, FALSE, "waiting"); if (!handle) { fprintf(stderr, "OpenEvent() failed in server thread!\n"); do_exit(EXIT_FAILURE); } fprintf(stderr, "waiting for datagram...\n"); SetEvent(handle); bytes=recvfrom(fd, buf, 1024, 0, &from, &fromlen); if (bytes==SOCKET_ERROR) { printerr(WSAGetLastError()); fprintf(stderr, " at recvfrom() call\n"); do_exit(EXIT_FAILURE); } else { printf("read %d bytes from socket\ndata follows:\n%s\n", bytes, buf); do_exit(EXIT_SUCCESS); } return 0; } WINAPI client_thread(int param) { struct protoent *udp; SOCKET fd; struct sockaddr_in sin; int bytes; const char buf[]="UDP is working"; udp=getprotobyname("udp"); if (udp==NULL) { printerr(WSAGetLastError()); fprintf(stderr, " at getprotobyname() call\n"); do_exit(EXIT_FAILURE); } fd=socket(AF_INET, SOCK_DGRAM, udp->p_proto); if (fd==INVALID_SOCKET) { printerr(WSAGetLastError()); fprintf(stderr, " at socket() call\n"); do_exit(EXIT_FAILURE); } memset(&sin, 0, sizeof(sin)); sin.sin_family=AF_INET; sin.sin_port=htons(9999); sin.sin_addr.s_addr=htonl(INADDR_LOOPBACK); if (sendto(fd, buf, strlen(buf), 0, (struct sockaddr *)&sin, sizeof(sin))==SOCKET_ERROR) { printerr(WSAGetLastError()); fprintf(stderr, " at sendto() call\n"); do_exit(EXIT_FAILURE); } else { fprintf(stderr, "sent udp packet.\n"); } return 0; } int main(void) { int serv_thread, cli_thread; int foo=0; HANDLE handle; HANDLE server_event; do_initialization(); handle=CreateEvent(NULL, FALSE, FALSE, "waiting"); if (!handle) { fprintf(stderr, "CreateEvent() failed!\n"); do_exit(EXIT_FAILURE); } server_event=OpenEvent(SYNCHRONIZE, FALSE, "waiting"); if (!server_event) { fprintf(stderr, "OpenEvent() failed in main thread!\n"); do_exit(EXIT_FAILURE); } handle=CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)server_thread, (LPVOID)&foo, 0, (LPDWORD)&serv_thread); if (!handle) { fprintf(stderr, "server CreateThread() failed!\n"); do_exit(EXIT_FAILURE); } else { if (WaitForSingleObject(server_event, 5000)!=WAIT_OBJECT_0) { fprintf(stderr, "WaitForSingleObject() failed!\n"); do_exit(EXIT_FAILURE); } fprintf(stderr, "server thread started...\n"); } handle=CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)client_thread, (LPVOID)&foo, 0, (LPDWORD)&cli_thread); if (!handle) { fprintf(stderr, "client CreateThread() failed!\n"); do_exit(EXIT_FAILURE); } else { fprintf(stderr, "client thread started...\n"); } sleep(30); fprintf(stderr, "test failed!\n"); WSACleanup(); return EXIT_FAILURE; }