Advertisement

Non-blocking UDP Client/Server

Started by June 22, 2006 11:53 AM
3 comments, last by GameDev.net 18 years, 8 months ago
Hi all, I've just got a non-blocking UDP client/server working and was just wondering if I am doing everything correctly. I've used this non-blocking TCP example as a reference - http://www.gamedev.net/community/forums/topic.asp?topic_id=39071 My code isn't using WaitForSingleObject(). I've only ever seen WaitForSingleObject() used with Treads so I wasn't exactly sure what its purpose was in the example above. Maybe I should be using it? Any other advice? My server - #include <stdlib.h> #include <sys/types.h> #include <winsock2.h> #include <stdio.h> #include <windows.h> int main() { WSADATA w; SOCKET s; struct sockaddr_in server; void * g_hAcceptEvent; WSANETWORKEVENTS NetworkEvents; int nRet; char buf[512]={0}; int rc; if (WSAStartup (0x0202, &w)) return EXIT_FAILURE; if (w.wVersion != 0x0202) { // wrong WinSock version! WSACleanup (); // unload ws2_32.dll return EXIT_FAILURE; } s=socket(AF_INET,SOCK_DGRAM,0); //open a UDP socket for use g_hAcceptEvent = WSACreateEvent(); if (WSA_INVALID_EVENT == g_hAcceptEvent) { printf("\nError occurred while WSACreateEvent()."); return EXIT_FAILURE; } if (SOCKET_ERROR == WSAEventSelect(s, g_hAcceptEvent, FD_READ | FD_WRITE | FD_ACCEPT | FD_CONNECT | FD_CLOSE)) { printf("\nError occurred while WSAEventSelect()."); WSACloseEvent(g_hAcceptEvent); return EXIT_FAILURE; } server.sin_family = AF_INET; server.sin_addr.s_addr = htonl(INADDR_ANY); server.sin_port = htons(12345); if(bind(s,(struct sockaddr*)&server,sizeof(server))!=0) return EXIT_FAILURE; while(1) { WSAEnumNetworkEvents(s, g_hAcceptEvent, &NetworkEvents); if(FD_READ==NetworkEvents.lNetworkEvents) { rc = recv (s, buf, sizeof(buf), 0); buf[rc]= (char) NULL; printf("Received: %s\n", buf); } printf(" %d \n",NetworkEvents.lNetworkEvents); Sleep(1000); } return EXIT_SUCCESS; } Client - #include <stdlib.h> #include <stdio.h> #include <time.h> #include <sys/types.h> #include <string.h> #include <winsock2.h> int main() { WSADATA w; SOCKET s; struct sockaddr_in server; struct tm; char str[1000]; time_t result,presult; char buf[512]; int rc; if (WSAStartup (0x0202, &w)) return EXIT_FAILURE; if (w.wVersion != 0x0202) { // wrong WinSock version! WSACleanup (); // unload ws2_32.dll return EXIT_FAILURE; } s = socket (AF_INET,SOCK_DGRAM,0); server.sin_family = AF_INET; server.sin_addr.s_addr = inet_addr("127.0.0.1"); server.sin_port = htons(12345); while(1) { printf("Enter Message: "); scanf("%s",str); sendto(s, str,strlen(str), 0, (struct sockaddr*) &server, sizeof(server)); } return EXIT_SUCCESS; } Thanks all for your help! Barry.
I don't use asynchronous sockets (I like berkeley, it's cross platform), so I'm not going to comment on your socket setup. I do think you should use recvfrom to track which client is sending the server stuff, though.
Winterdyne Solutions Ltd is recruiting - this thread for details!
Advertisement
You will need to replace these calls with a more porting-friendly method if you want to compile for another platform
WSACreateEvent
WSAEnumNetworkEvents
WSAEventSelect
WSACloseEvent

I would recommend doing this now if you are planning to do it later anyway. For a non-blocking socket you can just call the recv (or recvfrom as suggested) and if it fails with the error code WOULDBLOCK then there was no data ready. Some people will probably comment on whether this is a good idea for a server with a lot of connections though...

A full buffer will ignore arriving packets, so the newer packets get lost first.

This topic is closed to new replies.

Advertisement