XcodeのSwift/Playground環境が何かと便利に思う今日このごろですが、ネットワーク経由でデータを取得して、Playgroundでそのデータを利用してみました。
サーバはとても多機能なネットワークツールのsocatコマンドをMacのコンソールで走らせ、クライアントはPlaygroundからNSStreamを使いました。
brew install socat
Xcode 7.1.1 / Mac OSX 10.10.5
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 |
import UIKit let addr = "localhost" let port = 2525 var buffer = [UInt8](count: 255, repeatedValue: 0) var inp : NSInputStream? var out : NSOutputStream? NSStream.getStreamsToHostWithName(addr, port: port, inputStream: &inp, outputStream: &out) if let inputStream : NSInputStream = inp, outputStream : NSOutputStream = out{ inputStream.open() outputStream.open() if outputStream.streamError == nil && inputStream.streamError == nil { var cnt: NSInteger = 48 for _ in 1...10 { sleep(1) cnt += 1 let req = NSData(bytes: &cnt, length: sizeof(NSInteger)) print("write data \(req)") outputStream.write(UnsafePointer(req.bytes), maxLength:req.length) var readChars: Int = inputStream.read(&buffer, maxLength: buffer.count) if (readChars > 0) { print(buffer[0]) buffer[0] } else { inputStream.close() outputStream.close() break } } } } |
まずechoサーバに対して接続してテストします。socatコマンドとcatコマンドで以下のようにして実行します。
次は、このようなデータ送受信のしくみはそのままに、任意のデータを返してみます。
ノンプロックで通信するしくみをC言語で実装します。
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 |
#include <stdio.h> #include <termios.h> #include <fcntl.h> #include <time.h> int main(int argc, char const* argv[]) { struct termios save_settings; struct termios settings; char c; tcgetattr(0,&save_settings); settings = save_settings; settings.c_lflag &= ~(ECHO|ICANON); /* not echo back */ settings.c_cc[VTIME] = 0; settings.c_cc[VMIN] = 1; tcsetattr(0,TCSANOW,&settings); fcntl(0,F_SETFL,O_NONBLOCK); /* nonblock stdin */ while(1){ if((c = getchar()) != EOF){ printf("%c", rand()%64 + 48); } fflush(stdout); sleep(1); } tcsetattr(0,TCSANOW,&save_settings); return 0; } |
(こちらのsleepは不要でした。結果を出してしまったのでこのままで・・)
gcc -o nb nb.c
ランダムで返す値は、socatコマンドの表示がわかりやすいように、文字の領域にしました。
Swift側で受信をせず送信のみにして、netcat(nc)コマンドを使うと、パイプ処理ができます。
参考 :
http://stackoverflow.com/questions/26625373/how-to-implement-a-socket-connection-using-a-swift-playground
http://d.hatena.ne.jp/mFumi/20101002/1286003738