
这是一个简单的在 Linux 环境下使用 TCP/IP 传输数据的小例子,分为 Server 端和 Client 端,Server 端将 Leap Motion 处理后的数据传送给 Client 端。
Linux Socket 部分参考自 红薯 分享在开源中国的例子:Linux Socket 编程实例(一个Hello World程序);
Leap Motion 部分使用的是官方提供的 Sample 程序。
思路
1.TCP/IP 需要先初始化,使用代码进行端口绑定和监听。这部分代码可添加到 Leap Motion 监听类的初始化函数onInit()
中。
2.TCP/IP 中循环接收数据的部分可添加到 Leap Motion 的onFrame()
中。
3.在 Leap Motion 监听类退出时onExit()
,因同时关闭 Socket 的监听进程。
4.将 Leap Motion 处理后的整型数据通过stringstream作为中转,最后转换为char *型,送入缓冲区,发送。
5.Client 端接收到的为char *型,可通过字符串截取的方式取出数据并转换为整型。(该部分代码并未给出。)
Server 端
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 |
/******************************************************************************\ * Copyright (C) 2012-2014 Leap Motion, Inc. All rights reserved. * * Leap Motion proprietary and confidential. Not for distribution. * * Use subject to the terms of the Leap Motion SDK Agreement available at * * https://developer.leapmotion.com/sdk_agreement, or another agreement * * between Leap Motion and you, your company or other organization. * \******************************************************************************/ #include <iostream> #include <string.h> #include "Leap.h" #include <sys/socket.h> #include <unistd.h> #include <sys/types.h> #include <netinet/in.h> #include <time.h> #include <cstring> #include <stdlib.h> #include <sstream> #define SERVER_PORT 20000 #define LENGTH_OF_LISTEN_QUEUE 10 #define BUFFER_SIZE 20 #define SCREENX 1366 #define SCREENY 768 using namespace Leap; class SampleListener : public Listener { public: virtual void onInit(const Controller&); virtual void onConnect(const Controller&); virtual void onDisconnect(const Controller&); virtual void onExit(const Controller&); virtual void onFrame(const Controller&); virtual void onFocusGained(const Controller&); virtual void onFocusLost(const Controller&); virtual void onDeviceChange(const Controller&); virtual void onServiceConnect(const Controller&); virtual void onServiceDisconnect(const Controller&); private: }; const std::string fingerNames[] = {"Thumb", "Index", "Middle", "Ring", "Pinky"}; const std::string boneNames[] = {"Metacarpal", "Proximal", "Middle", "Distal"}; const std::string stateNames[] = {"STATE_INVALID", "STATE_START", "STATE_UPDATE", "STATE_END"}; int servfd,clifd; struct sockaddr_in servaddr,cliaddr; char buf[20]; void SampleListener::onInit(const Controller& controller) { if ((servfd = socket(AF_INET,SOCK_STREAM, 0 )) < 0 ) { std::cout<<"create socket error!"<<std::endl; exit( 1 ); } bzero( & servaddr, sizeof (servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(SERVER_PORT); servaddr.sin_addr.s_addr = htons(INADDR_ANY); if (bind(servfd,( struct sockaddr * ) & servaddr, sizeof (servaddr)) < 0 ) { std::cout<<"bind to port failure!"<<std::endl; exit( 1 ); } if (listen(servfd,LENGTH_OF_LISTEN_QUEUE) < 0 ) { std::cout<<"call listen failure!"<<std::endl; exit( 1 ); } socklen_t length = sizeof (cliaddr); clifd = accept(servfd,( struct sockaddr * ) & cliaddr, & length); if (clifd < 0 ) { std::cout<<"error comes when call accept!"<<std::endl; //break ; } std::cout << "Initialized" << std::endl; } void SampleListener::onConnect(const Controller& controller) { std::cout << "Connected" << std::endl; controller.enableGesture(Gesture::TYPE_CIRCLE); controller.enableGesture(Gesture::TYPE_KEY_TAP); controller.enableGesture(Gesture::TYPE_SCREEN_TAP); controller.enableGesture(Gesture::TYPE_SWIPE); } void SampleListener::onDisconnect(const Controller& controller) { // Note: not dispatched when running in a debugger. std::cout << "Disconnected" << std::endl; } void SampleListener::onExit(const Controller& controller) { std::cout << "Exited" << std::endl; } void SampleListener::onFrame(const Controller& controller) { std::cout<<"Begin Frame"<<std::endl; const Frame frame = controller.frame(); //Set a InteractionBox InteractionBox iBox = controller.frame().interactionBox(); //Set a HandList HandList hands = frame.hands(); for(HandList::const_iterator hl = hands.begin();hl != hands.end();++hl){ std::cout<<"Begin Hands"<<std::endl; //Get the 1st Hand const Hand hand = *hl; //Get the hand`s normal Vector and Direction const Vector handCenter = iBox.normalizePoint(controller.frame().hands()[0].stabilizedPalmPosition()); int mouse_x,mouse_y,screen_x,screen_y; mouse_x = handCenter.x * 65535; mouse_y = 65535 - handCenter.y * 65535; screen_x = handCenter.x*SCREENX; screen_y = (1-handCenter.y)*SCREENY; std::cout<<mouse_x<<mouse_y<<screen_x<<screen_y<<std::endl; std::stringstream ss; ss<<screen_x+10000<<screen_y+10000<<mouse_x<<mouse_y; std::string si = ss.str(); const char *c = si.c_str(); c = si.c_str(); strcpy(buf,c); send(clifd,buf,BUFFER_SIZE, 0 ); std::cout<<buf<<std::endl; } } void SampleListener::onFocusGained(const Controller& controller) { std::cout << "Focus Gained" << std::endl; } void SampleListener::onFocusLost(const Controller& controller) { std::cout << "Focus Lost" << std::endl; close(clifd); } void SampleListener::onDeviceChange(const Controller& controller) { std::cout << "Device Changed" << std::endl; const DeviceList devices = controller.devices(); for (int i = 0; i < devices.count(); ++i) { std::cout << "id: " << devices[i].toString() << std::endl; std::cout << " isStreaming: " << (devices[i].isStreaming() ? "true" : "false") << std::endl; } } void SampleListener::onServiceConnect(const Controller& controller) { std::cout << "Service Connected" << std::endl; } void SampleListener::onServiceDisconnect(const Controller& controller) { std::cout << "Service Disconnected" << std::endl; } int main(int argc, char** argv) { // Create a sample listener and controller SampleListener listener; Controller controller; // Have the sample listener receive events from the controller controller.addListener(listener); if (argc > 1 && strcmp(argv[1], "--bg") == 0) controller.setPolicy(Leap::Controller::POLICY_BACKGROUND_FRAMES); // Keep this process running until Enter is pressed std::cout << "Press Enter to quit..." << std::endl; std::cin.get(); // Remove the sample listener when done controller.removeListener(listener); return 0; } |
Client 端
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
#include <stdio.h> #include <sys/socket.h> #include <unistd.h> #include <sys/types.h> #include <netinet/in.h> #include <stdlib.h> #include <string.h> #include <time.h> #define SERVER_PORT 20000 #define CLIENT_PORT ((20001+rand())%65536) #define BUFFER_SIZE 20 char buf[BUFFER_SIZE]; void usage(char* name){ printf( " usage: %s IpAddr\n " ,name); } int main(int argc, char** argv){ int servfd,clifd,length = 0; struct sockaddr_in servaddr,cliaddr; socklen_t socklen = sizeof (servaddr); if (argc < 2 ){ usage(argv[ 0 ]); exit( 1 ); } if ((clifd = socket(AF_INET,SOCK_STREAM, 0 )) < 0 ){ printf( " create socket error!\n " ); exit( 1 ); } srand(time(NULL)); bzero( & cliaddr, sizeof (cliaddr)); cliaddr.sin_family = AF_INET; cliaddr.sin_port = htons(CLIENT_PORT); cliaddr.sin_addr.s_addr = htons(INADDR_ANY); bzero( & servaddr, sizeof (servaddr)); servaddr.sin_family = AF_INET; inet_aton(argv[ 1 ], & servaddr.sin_addr); servaddr.sin_port = htons(SERVER_PORT); if( bind(clifd, (struct sockaddr* ) &cliaddr, sizeof (cliaddr)) < 0 ){ printf( " bind to port %d failure!\n " ,CLIENT_PORT); exit( 1 ); } if (connect(clifd,( struct sockaddr * ) & servaddr, socklen) < 0 ){ printf( " can't connect to %s!\n ", argv[ 1 ]); exit( 1 ); } while(1){ length = recv(clifd, buf, BUFFER_SIZE, 0); if (length < 0){ printf( " error comes when recieve data from server %s! ", argv[1] ); exit( 1 ); } printf( "%s\n",buf); } close(clifd); return 0; } |
Makefile
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
OS := $(shell uname) ARCH := $(shell uname -m) ifeq ($(OS), Linux) ifeq ($(ARCH), x86_64) LEAP_LIBRARY := ../lib/x64/libLeap.so -Wl,-rpath,../lib/x64 else LEAP_LIBRARY := ../lib/x86/libLeap.so -Wl,-rpath,../lib/x86 endif else # OS X LEAP_LIBRARY := ../lib/libLeap.dylib endif all:TCPS TCPC TCPS: TCPS.cpp $(CXX) -Wall -g -I../header TCPS.cpp -o TCPS $(LEAP_LIBRARY) ifeq ($(OS), Darwin) install_name_tool -change @loader_path/libLeap.dylib ../lib/libLeap.dylib TCPS endif TCPC: TCPC.c $(CC) -Wall TCPC.c -o TCPC .PHONY:all clean: rm -rf TCPS TCPS.dSYM TCPC TCPC.dSYM |
如无注明,均为原创。转载请注明: 转载自MITGAI`S THINKING
本文链接地址: Linux Socket 传输 Leap Motion 数据示例
本文链接地址: Linux Socket 传输 Leap Motion 数据示例
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。
如果本文对您生活或工作产生了积极影响,那我非常高兴。
如果您愿意为文章的内容或想法提供支持,欢迎点击下边的捐赠按钮,资助作者创作更多高价值高品质的内容。
如果您愿意为文章的内容或想法提供支持,欢迎点击下边的捐赠按钮,资助作者创作更多高价值高品质的内容。