liblo  0.32
example_tcp_echo_server.c
1 /*
2  * Copyright (C) 2012 Steve Harris, Stephen Sinclair
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License as
6  * published by the Free Software Foundation; either version 2.1 of the
7  * License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU Lesser General Public License for more details.
13  *
14  * $Id$
15  */
16 
17 /* Run this program in one terminal with no arguments,
18  * $ ./example_tcp_echo_server
19  * and in another terminal with argument 1,
20  * $ ./example_tcp_echo_server 1
21  * Now watch the /test message ping back and forth a few times!
22  */
23 
24 #include <stdio.h>
25 #include <stdlib.h>
26 #ifndef WIN32
27 #include <unistd.h>
28 #include <sys/time.h>
29 #endif
30 #include <signal.h>
31 #include "lo/lo.h"
32 
33 int done = 0;
34 int count = 0;
35 
36 void error(int num, const char *m, const char *path);
37 
38 int echo_handler(const char *path, const char *types, lo_arg ** argv,
39  int argc, lo_message data, void *user_data);
40 
41 int quit_handler(const char *path, const char *types, lo_arg ** argv,
42  int argc, lo_message data, void *user_data);
43 
44 void ctrlc(int sig)
45 {
46  done = 1;
47 }
48 
49 int main(int argc, char *argv[])
50 {
51  const char *port = "7770";
52  int do_send = 0;
53 
54  if (argc > 1 && argv[1][0]=='1') {
55  do_send = 1;
56  port = "7771";
57  }
58 
59  /* start a new server on port 7770 */
60  lo_server_thread st = lo_server_thread_new_with_proto(port, LO_TCP, error);
61  if (!st) {
62  printf("Could not create server thread.\n");
63  exit(1);
64  }
65 
67 
68  /* add method that will match the path /quit with no args */
69  lo_server_thread_add_method(st, "/quit", "", quit_handler, NULL);
70 
71  /* add method that will match any path and args */
72  lo_server_thread_add_method(st, NULL, NULL, echo_handler, s);
73 
75 
76  signal(SIGINT,ctrlc);
77 
78  printf("Listening on TCP port %s\n", port);
79 
80  lo_address a = 0;
81  if (do_send) {
82  a = lo_address_new_with_proto(LO_TCP, "localhost", "7770");
83  if (!a) {
84  printf("Error creating destination address.\n");
85  exit(1);
86  }
87  int r = lo_send_from(a, s, LO_TT_IMMEDIATE, "/test", "ifs",
88  1, 2.0f, "3");
89  if (r < 0)
90  printf("Error sending initial message.\n");
91  if (a) lo_address_free(a);
92  a = 0;
93  }
94 
95  while (!done) {
96 #ifdef WIN32
97  Sleep(1);
98 #else
99  sleep(1);
100 #endif
101  }
102 
104 
105  return 0;
106 }
107 
108 void error(int num, const char *msg, const char *path)
109 {
110  printf("liblo server error %d in path %s: %s\n", num, path, msg);
111  fflush(stdout);
112 }
113 
114 /* catch any incoming messages, display them, and send them
115  * back. */
116 int echo_handler(const char *path, const char *types, lo_arg ** argv,
117  int argc, lo_message data, void *user_data)
118 {
119  int i;
120  lo_message m = (lo_message)data;
122  lo_server s = (lo_server)user_data;
123  const char *host = lo_address_get_hostname(a);
124  const char *port = lo_address_get_port(a);
125 
126  count ++;
127 
128 #ifdef WIN32
129  Sleep(1);
130 #else
131  sleep(1);
132 #endif
133 
134  printf("path: <%s>\n", path);
135  for (i = 0; i < argc; i++) {
136  printf("arg %d '%c' ", i, types[i]);
137  lo_arg_pp((lo_type)types[i], argv[i]);
138  printf("\n");
139  }
140 
141  if (!a) {
142  printf("Couldn't get message source, quitting.\n");
143  done = 1;
144  return 0;
145  }
146 
147  int r = lo_send_message_from(a, s, path, m);
148  if (r < 0)
149  printf("Error sending back message, socket may have closed.\n");
150  else
151  printf("Sent message back to %s:%s.\n", host, port);
152 
153  if (count >= 3) {
154  printf("Got enough messages, quitting.\n");
155  done = 1;
156  }
157 
158  return 0;
159 }
160 
161 int quit_handler(const char *path, const char *types, lo_arg ** argv,
162  int argc, lo_message data, void *user_data)
163 {
164  done = 1;
165  printf("quitting\n\n");
166  fflush(stdout);
167 
168  return 0;
169 }
lo_type
An enumeration of the OSC types liblo can send and receive.
Definition: lo_osc_types.h:61
void lo_address_free(lo_address t)
Free the memory used by the lo_address object.
int lo_send_from(lo_address targ, lo_server from, lo_timetag ts, const char *path, const char *type,...)
Send a OSC formatted message to the address specified, from the same socket as the specified server.
lo_address lo_address_new_with_proto(int proto, const char *host, const char *port)
Declare an OSC destination, given IP address and port number, specifying protocol.
#define LO_TT_IMMEDIATE
A timetag constant representing "now".
Definition: lo_osc_types.h:151
lo_address lo_message_get_source(lo_message m)
Returns the source (lo_address) of an incoming message.
const char * lo_address_get_port(lo_address a)
Return the port/service name of a lo_address object.
const char * lo_address_get_hostname(lo_address a)
Return the hostname of a lo_address object.
int lo_send_message_from(lo_address targ, lo_server serv, const char *path, lo_message msg)
Send a lo_message object to target targ from address of serv.
void lo_arg_pp(lo_type type, void *data)
Pretty-print a set of typed arguments.
int lo_server_thread_start(lo_server_thread st)
Start the server thread.
lo_server_thread lo_server_thread_new_with_proto(const char *port, int proto, lo_err_handler err_h)
Create a new server thread to handle incoming OSC messages, specifying protocol.
lo_server lo_server_thread_get_server(lo_server_thread st)
Return the lo_server for a lo_server_thread.
void lo_server_thread_free(lo_server_thread st)
Free memory taken by a server thread.
lo_method lo_server_thread_add_method(lo_server_thread st, const char *path, const char *typespec, lo_method_handler h, const void *user_data)
Add an OSC method to the specifed server thread.
struct lo_server_ * lo_server
An object representing an instance of an OSC server.
Definition: lo_types.h:85
struct lo_address_ * lo_address
A reference to an OSC service.
Definition: lo_types.h:45
struct lo_message_ * lo_message
A low-level object used to represent messages passed over OSC.
Definition: lo_types.h:60
struct lo_server_thread_ * lo_server_thread
An object representing a thread containing an OSC server.
Definition: lo_types.h:92
Union used to read values from incoming messages.
Definition: lo_osc_types.h:104