00001 /** WOscTCPClient.cpp - A streaming OSC client using posix threads and sockets 00002 * 00003 * Created on: Apr 21, 2010 00004 * Author: uli 00005 */ 00006 00007 #include "WOscTcpClient.h" 00008 00009 #if OS_IS_LINUX == 1 || OS_IS_MACOSX == 1 || OS_IS_CYGWIN == 1 00010 00011 #include <fcntl.h> 00012 #include <sys/socket.h> 00013 00014 00015 /** Implements a full featured OSC client with TCP transport. 00016 * @param threading 00017 * If true, all reception happens in a separate thread and does not require any 00018 * select logic in the main loop, but you have to take care when calling main 00019 * thread code from the OSC message handlers/methods. 00020 * If false, threading is disabled and the reception must be implemented by a 00021 * select statement. On input WOscTcpClient::NetworkReceive() must be called. 00022 * The socket is switched to non blocking automatically. See the streaming 00023 * server example for further details. 00024 */ 00025 WOscTcpClient::WOscTcpClient(bool threading) : WOscTcpHandler(threading) 00026 {} 00027 00028 WOscTcpClient::~WOscTcpClient() 00029 { 00030 Close(); 00031 } 00032 00033 /** Connect to a OSC server at a given address. 00034 * Starts a receiver thread which handles any replies from the server when this 00035 * class was constructed with threading enabled. If not, the socket is set to 00036 * non blocking and can be used in a select statement. 00037 */ 00038 WOscTcpClient::Error 00039 WOscTcpClient::Connect(const TheNetReturnAddress& serverAddress) 00040 { 00041 // Check if reception thread is already running 00042 if ( GetRxThreadID() > 0 ) 00043 return WOS_ERR_ALREADY_RUNNING; 00044 00045 // Check if someone established a connection already 00046 if ( GetSocketID() >= 0 ) 00047 return WOS_ERR_ALREADY_CONNECTED; 00048 00049 // Create socket 00050 int sock = socket(AF_INET, SOCK_STREAM, 0); 00051 if (sock < 0) { 00052 return WOS_ERR_SOCKET_CREATE; 00053 } 00054 00055 // Connect 00056 int ret = connect(sock, (struct sockaddr*) &serverAddress.m_addr, sizeof(serverAddress.m_addr)); 00057 if ( ret < 0 ) { 00058 close(sock); 00059 return WOS_ERR_SOCKET_CONNECT; 00060 } 00061 00062 // starts thread if threading is enabled 00063 WOscTcpHandler::Error err = Start(sock, serverAddress); 00064 if ( err != WOscTcpHandler::WOS_ERR_NO_ERROR ) 00065 close(sock); 00066 00067 return err; 00068 } 00069 00070 /** Close the receiving socket and shutdown the receiving thread if in 00071 * threading mode. 00072 */ 00073 WOscTcpClient::Error 00074 WOscTcpClient::Close() 00075 { 00076 // Check if reception thread has already been shut down 00077 if ( GetThreading() && GetRxThreadID() ) 00078 return WOS_ERR_ALREADY_CLOSED; 00079 // Check if socket still 00080 if ( GetSocketID() < 0 ) 00081 return WOS_ERR_DISCONNECTED; 00082 00083 WOscTcpHandler::Error err = Stop(); 00084 00085 // close socket 00086 int ret = close(GetSocketID()); 00087 if ( ret ) { 00088 // std::cout<<"Close failed."<<std::endl; 00089 } 00090 return err; 00091 } 00092 00093 #elif OS_IS_WIN32 == 1 00094 /* currently this example does not support windows - volunteers? 00095 # include "windows.h" 00096 # include "winsock2.h" 00097 # define socklen_t int 00098 */ 00099 # warning "WOscTcpClient not supported on this platform" 00100 #endif