liblo: example_tcp_echo_server.c Source File

liblo 0.36

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
33int done = 0;
34int count = 0;
35
36void error(int num, const char *m, const char *path);
37
38int echo_handler(const char *path, const char *types, lo_arg ** argv,
39 int argc, lo_message data, void *user_data);
40
41int quit_handler(const char *path, const char *types, lo_arg ** argv,
42 int argc, lo_message data, void *user_data);
43
44void ctrlc(int sig)
45{
46 done = 1;
47}
48
49int 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
66 lo_server s = lo_server_thread_get_server(st);
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
74 lo_server_thread_start(st);
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
103 lo_server_thread_free(st);
104
105 return 0;
106}
107
108void 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. */
116int 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;
121 lo_address a = lo_message_get_source(m);
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
161int 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
lo_type
An enumeration of the OSC types liblo can send and receive.
Definition lo_osc_types.h:61
lo_address_free
void lo_address_free(lo_address t)
Free the memory used by the lo_address object.
lo_send_from
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_new_with_proto
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.
LO_TT_IMMEDIATE
#define LO_TT_IMMEDIATE
A timetag constant representing "now".
Definition lo_osc_types.h:151
lo_address_get_hostname
const char * lo_address_get_hostname(lo_address a)
Return the hostname of a lo_address object.
lo_message_get_source
lo_address lo_message_get_source(lo_message m)
Returns the source (lo_address) of an incoming message.
lo_send_message_from
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.
lo_address_get_port
const char * lo_address_get_port(lo_address a)
Return the port/service name of a lo_address object.
lo_arg_pp
void lo_arg_pp(lo_type type, void *data)
Pretty-print a set of typed arguments.
lo.h
lo_server_thread_start
int lo_server_thread_start(lo_server_thread st)
Start the server thread.
lo_server_thread_new_with_proto
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_thread_get_server
lo_server lo_server_thread_get_server(lo_server_thread st)
Return the lo_server for a lo_server_thread.
lo_server_thread_free
void lo_server_thread_free(lo_server_thread st)
Free memory taken by a server thread.
lo_server_thread_add_method
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.
lo_server
struct lo_server_ * lo_server
An object representing an instance of an OSC server.
Definition lo_types.h:85
lo_address
struct lo_address_ * lo_address
A reference to an OSC service.
Definition lo_types.h:45
lo_message
struct lo_message_ * lo_message
A low-level object used to represent messages passed over OSC.
Definition lo_types.h:60
lo_server_thread
struct lo_server_thread_ * lo_server_thread
An object representing a thread containing an OSC server.
Definition lo_types.h:92
lo_arg
Union used to read values from incoming messages.
Definition lo_osc_types.h:104