From 8930bf8e42c9727d308d1d07c5fd07b80791f0cd Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 29 Jan 2013 12:29:00 -0800 Subject: [PATCH] add a UDPSocket class to abstract communication to agents --- Source/UDPSocket.cpp | 70 +++++++++++++++++++++++++++++ Source/UDPSocket.h | 33 ++++++++++++++ interface.xcodeproj/project.pbxproj | 6 +++ 3 files changed, 109 insertions(+) create mode 100644 Source/UDPSocket.cpp create mode 100644 Source/UDPSocket.h diff --git a/Source/UDPSocket.cpp b/Source/UDPSocket.cpp new file mode 100644 index 0000000000..4b0cad1200 --- /dev/null +++ b/Source/UDPSocket.cpp @@ -0,0 +1,70 @@ +// +// UDPSocket.cpp +// interface +// +// Created by Stephen Birarda on 1/28/13. +// Copyright (c) 2013 Rosedale Lab. All rights reserved. +// + +#include "UDPSocket.h" +#include +#include +#include + +struct sockaddr_in UDPSocket::sockaddr_util(char* hostname, int port) { + sockaddr_in dest_address; + + dest_address.sin_family = AF_INET; + dest_address.sin_addr.s_addr = inet_addr(hostname); + dest_address.sin_port = htons((uint16_t)port); + + return dest_address; +} + +struct sockaddr_in dest_sockaddr; + +UDPSocket::UDPSocket(int listeningPort) { + // create the socket + handle = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + + if (handle <= 0) { + printf("Failed to create socket.\n"); + return; + } + + // instantiate the re-usable dest_sockaddr with a dummy IP and port + dest_sockaddr = UDPSocket::sockaddr_util((char *) "1.0.0.0", 1); + + // bind the socket to the passed listeningPort + sockaddr_in bind_address = UDPSocket::sockaddr_util(INADDR_ANY, listeningPort); + + if (bind(handle, (const sockaddr*) &bind_address, sizeof(sockaddr_in)) < 0) { + printf("Failed to bind socket to port %d.\n", listeningPort); + return; + } + + // set socket as non-blocking + int nonBlocking = 1; + if (fcntl(handle, F_SETFL, O_NONBLOCK, nonBlocking) == -1) { + printf("Failed to set non-blocking socket\n"); + return; + } +} + +int UDPSocket::send(char * dest_address, int dest_port, const void *data, int length_in_bytes) { + + // change address and port on reusable global to passed variables + dest_sockaddr.sin_addr.s_addr = inet_addr(dest_address); + dest_sockaddr.sin_port = htons((uint16_t)dest_port); + + // send data via UDP + int sent_bytes = sendto(handle, (const char*)data, length_in_bytes, + 0, (sockaddr*)&dest_address, sizeof(sockaddr_in)); + + if (sent_bytes != length_in_bytes) { + printf("Failed to send packet: return value = %d\n", sent_bytes); + return false; + } + + return sent_bytes; +} diff --git a/Source/UDPSocket.h b/Source/UDPSocket.h new file mode 100644 index 0000000000..4247184b6a --- /dev/null +++ b/Source/UDPSocket.h @@ -0,0 +1,33 @@ +// +// UDPSocket.h +// interface +// +// Created by Stephen Birarda on 1/28/13. +// Copyright (c) 2013 Rosedale Lab. All rights reserved. +// + +#ifndef __interface__UDPSocket__ +#define __interface__UDPSocket__ + +#include +#include + +class UDPSocket { + public: + static struct sockaddr_in sockaddr_util(char *address, int port); + + UDPSocket(int listening_port); + int send(char * dest_address, int dest_port, const void *data, int length_in_bytes); + private: + UDPSocket(); // private default constructor + int handle; + + struct AgentData { + char * address; + int listening_port; + }; + + AgentData *known_agents; +}; + +#endif /* defined(__interface__UDPSocket__) */ diff --git a/interface.xcodeproj/project.pbxproj b/interface.xcodeproj/project.pbxproj index a1f20f2f5b..b8c2db7b50 100644 --- a/interface.xcodeproj/project.pbxproj +++ b/interface.xcodeproj/project.pbxproj @@ -54,6 +54,7 @@ 533B578716B2160C00FCABF1 /* grayson.raw in CopyFiles */ = {isa = PBXBuildFile; fileRef = 533B578516B2160600FCABF1 /* grayson.raw */; }; 533BF9D516B31A4700AC31BB /* jeska.raw in CopyFiles */ = {isa = PBXBuildFile; fileRef = 533BF9D316B31A3B00AC31BB /* jeska.raw */; }; 538BA8A316B1B71E000BF99C /* love.raw in CopyFiles */ = {isa = PBXBuildFile; fileRef = 538BA8A216B1B719000BF99C /* love.raw */; }; + 539853CE16B765EE00B2D585 /* UDPSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 539853CC16B765EE00B2D585 /* UDPSocket.cpp */; }; B6BDADE115F44A9D002A07DF /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B6BDADDE15F444DB002A07DF /* CoreServices.framework */; }; B6BDADE215F44AA5002A07DF /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B6BDADD815F444C1002A07DF /* CoreAudio.framework */; }; B6BDADE315F44AB0002A07DF /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B6BDADDA15F444C9002A07DF /* AudioToolbox.framework */; }; @@ -509,6 +510,8 @@ 533B578516B2160600FCABF1 /* grayson.raw */ = {isa = PBXFileReference; lastKnownFileType = file; path = grayson.raw; sourceTree = ""; }; 533BF9D316B31A3B00AC31BB /* jeska.raw */ = {isa = PBXFileReference; lastKnownFileType = file; path = jeska.raw; sourceTree = ""; }; 538BA8A216B1B719000BF99C /* love.raw */ = {isa = PBXFileReference; lastKnownFileType = file; path = love.raw; sourceTree = ""; }; + 539853CC16B765EE00B2D585 /* UDPSocket.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UDPSocket.cpp; sourceTree = ""; }; + 539853CD16B765EE00B2D585 /* UDPSocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UDPSocket.h; sourceTree = ""; }; 8DD76F6C0486A84900D96B5E /* interface */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = interface; sourceTree = BUILT_PRODUCTS_DIR; }; B6BDADD815F444C1002A07DF /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; }; B6BDADDA15F444C9002A07DF /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; @@ -628,6 +631,8 @@ 5325C24D16AF4DBE0051A40B /* util.cpp */, 5325C24E16AF4DBE0051A40B /* util.h */, 5325C24F16AF4DBE0051A40B /* world.h */, + 539853CC16B765EE00B2D585 /* UDPSocket.cpp */, + 539853CD16B765EE00B2D585 /* UDPSocket.h */, ); path = Source; sourceTree = ""; @@ -1368,6 +1373,7 @@ 5325C26016AF4DBE0051A40B /* texture.cpp in Sources */, 5325C26116AF4DBE0051A40B /* util.cpp in Sources */, 5325C26416AF4E2C0051A40B /* audio.cpp in Sources */, + 539853CE16B765EE00B2D585 /* UDPSocket.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; };