SlideShare a Scribd company logo
1 of 48
Download to read offline
(c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6
60分でわかるソケットプログラミン
グ
60分でわかるソケットプログラミン
グ
木本雅彦 <kimoto@soum.co.jp>
<kimoto@ohnolab.org>
株式会社創夢 第三開発部 シニアプロジェクトマネージャ
初版:2010年4月作成、改定版:2015年3月作成
(c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6
創夢とはどういう会社か
UNIXとTCP/IPネットワークに強い会社
全員がUNIXに詳しい
全員がIPに詳しい
ということは → 全社員がネットワークプログラミングくら
い出来るよね!?
ということで、60分レクチャーです
1/47
(c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6
この発表での前提条件
C言語でのプログラミングはできる
system call programming
file I/O basics
TCP/IPの基礎は理解している
OSI階層モデル
IPアドレス、ヘッダの構造など
2/47
(c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6
IPというプロトコルについて
IP = InternetProtocol
はじめに: ホストにはIPアドレスがついているらしいぜ
(以下略。知らない人は自力で勉強してください)
3/47
(c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6
TCPとUDPというプロトコル
TCP: Transmission Control Protocol
送達確認(ACK)の利用による信頼性のある通信
輻輳制御による「フェアな」通信量の制御
UDP: User Datagram Protocol
信頼性のない通信
パケット単位でデータを投げるだけ
4/47
(c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6
port番号
TCP, UDPで用いる通信口の番号
符号なし16bit
通信相手のアプリケーションを同定する
5/47
(c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6
well-known portとephemeral port
well-known port
代表的なサービスに割り当てられた番号
0 - 1023
IANAが管理している
ephemeral port
使い捨てポート
RFCでのdynamic port: 49152〜65535
Linuxの実装: 32768〜61000
古いBSDの実装: 1024〜4999
6/47
(c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6
一応IPv6について、ひとこと
次世代インターネットプロトコル
といいつつ、すでに実用化されている
IPアドレスが128bitに拡張されたという一点がもっとも
重要
アドレスの自動設定
マルチキャストの積極的な利用
7/47
(c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6
UNIXのプロセス間通信
pipe
双方向パイプ
FIFO
共有メモリ(SYSV由来)
セマフォ(SYSV由来)
signal
socket(BSD由来)
8/47
(c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6
socket
4.2BSDで導入されたTCP/IPの抽象化および実装
通信路の片方の末端を指し示す
ファイルデスクリプタで表される
→ネットワーク通信をファイルI/Oと同様に記述できる
9/47
(c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6
余談:socketという敗北
4.2BSDでsocketが導入されたのは、従来のUNIXの
ようにファイルシステム上にネットワークI/Oをマッピングで
きなかったため
主に性能上の理由
これが後々まで影響を及ぼす
例:jailやDocker(コンテナ型仮想化)において、ネットワークの制約の
ための枠組みが別途必要になる
10/47
(c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6
サーバクライアントモデル
ネットワーク通信のモデル化の一つ
vs Peer to Peer
サーバ
サービスを提供する側
要求を待って処理した結果を返す
クライアント
サービスを利用する側
サーバに接続し要求を出し処理結果を受け取る
11/47
(c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6
サーバクライアントの通信の流れ
12/47
(c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6
サーバ側の処理の流れ
socket(2)でsocketを作る
bind(2)でsocketに待受アドレスとポートを指定する
listen(2)で待受開始
select(2)で複数ソケットのイベントループを回す
接続があったらaccept(2)で受信して通信用ソケット
を得る
read(2), write(2)で送受信
13/47
(c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6
socket(2)
ソケットを作成するsystemcall
ソケットを表すファイルデスクリプタを返す
int socket(int domain, int type, int protocol);
domain: PF_INET, PF_INET6, ....
type: SOCK_STREAM, SOCK_DGRAM, ..
protocol: IPPROTO_IP, ...
14/47
(c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6
bind(2)
ソケットに名前をつける
名前とは:
IPアドレス
ポート番号
int bind(int s, const struct sockaddr *addr, socklen_t addrlen);
第2引数で名前=アドレスを指定する
15/47
(c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6
listen(2)
接続を待ち受ける
int listen(int s, int backlog);
backlogは最大保留数
16/47
(c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6
accept(2)
TCPの接続を受けつけ、dynamic portを割り当てる
int accept(int s, struct sockaddr * restrict addr,
socklen_t * restrict addrlen);
17/47
(c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6
イベントドリブン型プログラミング
外部からのイベントを契機に処理を駆動するプログラミ
ングモデル
イベント待ち受け
イベント受信
ディスパッチ
if文の羅列による分岐
ハンドラ/ジャンプテーブル
タイマ処理と合わせて擬似スレッドも実現できる
18/47
(c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6
select(2)システムコール
fd_set: fdの集合(ビットマップ)
read/write/errでチェックするfdを指定(複数可)
selectで待つ
fd_setにイベントが発生したsocketのfdがセットされる
19/47
(c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6
典型的なselect loop
sock = accept(....);
for (;;) {
FD_ZERO(&fds);
FD_SET(sock, &fds);
result = select(getdtablesize(),&fds,NULL,NULL, NULL);
if (FD_ISSET(sock,&fds)) {
**** read from socket ******
}
}
20/47
(c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6
多重待受のselect loop
listenしているポートもselectの対象にする
listen(lsock, ....);
for (;;) {
FD_ZERO(&fds);
FD_SET(lsock, &fds);
if (sock >= 0) {FD_SET(sock, &fds);}
result = select(getdtablesize(),&fds,NULL,NULL, NULL);
if (FD_ISSET(lsock,&fds)) {
sock = accept(lsock, ...);
continue;
}
if (sock >= 0 && FD_ISSET(sock,&fds)) {
**** read from socket ******
}
}
21/47
(c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6
クライアント側の処理の流れ
socket(2)でsocketを作る
bind(2)でsocketに通信先アドレスとポートを指定す
る
connect(2)で接続する
read(2), write(2)で送受信
22/47
(c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6
connect(2)
ソケット経由で接続開始する
int connect(int s, const struct sockaddr *name, socklen_t namelen);
23/47
(c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6
readn, writen
socketからの読み書きは1度のread/writeで完了す
る保証がない
指定した長さが完了するまでread/writeを繰り返す
必要がある
readn() / writen() 関数を使う
cf. Stevens' UNIX Network Programming
ただしブロックしてしまうので注意が必要
24/47
(c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6
sample code of writen:
int
writen(int fd,char *ptr,size_t size)
{
int i;
while(size > 0) {
if ((i = write(fd,ptr,size)) < 0) return i;
ptr += i;
size -= i;
}
return size;
}
25/47
(c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6
UDPとTCPのプログラミングの違い
UDPクライアントはbindしなくていい(してもいい)
UDPクライアントはconnectしなくていい(してもいい)
UDPはsendto(2)/recvfrom(2)で相手を指定して
送受信できる
connectしていればread/writeでもよい
26/47
(c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6
文字列からIPアドレスを得る古い方法
inet_aton
IPアドレスの文字列を数値に変換する
gethostbyname
ホスト名からIPアドレスを得る
gethostbyname2
AddressFamilyを指定してホスト名からIPアドレスを得る
getservbyname
サービス名からポート番号を得る
27/47
(c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6
IPアドレスを得る新しい方法
getaddrinfoを使ったクライアントの例
getaddrinfo(peer, buf, &hints, &res0));
s = -1;
for (res = res0; res; res = res->ai_next) {
s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (s < 0) continue;
connect(s, res->ai_addr, res->ai_addrlen);
break;
}
28/47
(c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6
ソケットが使っているアドレスを得る方法
getsockname
ソケットの自分側のsockaddrを得る
getpeername
ソケットの相手側のsockaddrを得る
29/47
(c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6
poll, libevent
selectを使った実装は重くなる
fdごとにif文でチェックするため
poll(struct pollfd fds[], nfds_t nfds, int
timeout);
チェックのコストが低い
libevent
イベントハンドラを記述するだけ
socket以外のイベントも監視できる
30/47
(c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6
タイマ処理
タイマ割り込みによる定期的な処理
alarm(unsigned int seconds);
setitimer(int which, .....);
selectのtimeoutを用いてタイマ処理を実装すること
もある
31/47
(c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6
selectとsignal
signalを受信してselectを抜ける場合があるので注
意
タイマ割り込みなど
selectがエラーで終了したら、errnoの値を調べる必要がある
do {
result = select(getdtablesize(),&fds,&wfds,NULL, &tv2);
} while((result < 0) && (errno == EINTR));
32/47
(c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6
bind: address already in use
bindしようとしたら、他のプロセスが既にportを使って
いる
プロセスが異常終了した後、サーバーを再起動すると
出ることがある
setsockopt(s, SOL_SOCKET, SO_REUSEPORT, (char *)&sockopt, sizeof(sockopt));
33/47
(c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6
setsockopt
socketの動作を設定する
SO_REUSEADDR enables local address reuse
SO_REUSEPORT enables duplicate address and port bindings
SO_KEEPALIVE enables keep connections alive
SO_DONTROUTE enables routing bypass for outgoing messages
SO_LINGER linger on close if data present
.....
34/47
(c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6
non blocking socket
複数のサーバに同時に非同期にconnectしたい場合
サーバとクライアントを兼ねている場合
e.g. bgpd, P2P application
connectでblockしない
f = fcntl(s, F_GETFL);
fcntl(s, F_SETFL, f | O_NONBLOCK);
35/47
(c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6
自分のIPアドレスを得る方法
ダメな例
gethostname() → gethostbyname()
多くの場合は127.0.0.1になる
実用的な例
UDP socketを作る
遠くのアドレスに向けてconnectする
getsocknameする
ただし経路がない場合はこの方法は使えない
36/47
(c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6
struct sockaddr
異なるプロトコルのアドレスを格納するための構造体
struct sockaddr {
unsigned char sa_len; /* total length */
sa_family_t sa_family; /* address family */
char sa_data[14]; /* actually longer; address value */
};
OSの違いによるsa_lenの有無に注意が必要
領域を確保するためには、sockaddr_storageを使う
37/47
(c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6
UNIX domain socket
いわゆる名前付きパイプ
単一ホスト内の通信に使う
PF_UNIX or PF_LOCAL
bindする時にパス名を使う
実際にファイルが作成される
e.g. try, ls -la /tmp/
38/47
(c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6
socketpair(2)
名前なしパイプ
連結した二つのsocketを返す
パイプと同様に使える
双方向に通信可能
39/47
(c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6
コネクション切断を識別する
selectでreadableなのにreadすると0byte
→ connectionが切れている
この処理をしないとselect loopが回り続けるので注
意
40/47
(c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6
inetd: Internet super daemon
クライアントからの待ち受けをinetdが行う
接続があったら、プロセスに引き渡す
socketがプロセスの標準入出力に割り当てられる
標準入出力のI/Oだけでサーバが記述できる
41/47
(c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6
daemon化するということ
daemon化には決まった手順がある
2度forkした後、途中のprocessを終了させ、initの子供になる
標準入出力を/dev/nullに割り当てる
制御端末を切り離す
通常はroot directoryに移動する
see daemon(3)
42/47
(c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6
raw socket
IPペイロードを直接入出力できる
ICMP, OSPFなどで使われている
see ping
root権限が必要
よって、pingはsetuidされている
43/47
(c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6
BPF: Berkley Packet Filter
生のEthernet Frameを送受信できる
/dev/bpf?をopenする
ioctlでインタフェースを割り当てる
readするとBPFヘッダがついてくる
複数のパケットが読める場合もある
writeするとそのままEthernet I/Fに出て行く
read時にfilterを記述できる
filterは「状態マシン」
44/47
(c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6
Packet Socket : LinuxでL2のパケットを
送受信する方法
PF_PACKET, SOCK_RAWを指定してsocketを作
る
L2のパケットを直接送受信できる
インタフェースはbind()で割り当てる
簡単なフィルタはあるが、主にPPPoE用と思われる
送受信はread()/write()で行う
sock = socket(PF_PACKET, SOCK_RAW, 0);
45/47
(c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6
パケット構造設計の注意点
独自でバイナリ形式のプロトコルを設計する場合
バージョン番号はつけること
パケットの長さは先頭部分で明示したほうがよい
メモリ領域の確保のため
ヘッダとボディとに分けるとよい
ボディはTLV(Type, Length, Value)でいいかもしれない
46/47
(c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6
Where should you start from?
inetd
1 session server and client
multi-session server
and more...
47/47

More Related Content

What's hot

C++ マルチスレッドプログラミング
C++ マルチスレッドプログラミングC++ マルチスレッドプログラミング
C++ マルチスレッドプログラミングKohsuke Yuasa
 
ネットワーク ゲームにおけるTCPとUDPの使い分け
ネットワーク ゲームにおけるTCPとUDPの使い分けネットワーク ゲームにおけるTCPとUDPの使い分け
ネットワーク ゲームにおけるTCPとUDPの使い分けモノビット エンジン
 
Halo2 におけるHFSM(階層型有限状態マシン) 【ビヘイビアツリー解説】
Halo2 におけるHFSM(階層型有限状態マシン)  【ビヘイビアツリー解説】Halo2 におけるHFSM(階層型有限状態マシン)  【ビヘイビアツリー解説】
Halo2 におけるHFSM(階層型有限状態マシン) 【ビヘイビアツリー解説】Youichiro Miyake
 
PFN のオンプレML基盤の取り組み / オンプレML基盤 on Kubernetes 〜PFN、ヤフー〜
PFN のオンプレML基盤の取り組み / オンプレML基盤 on Kubernetes 〜PFN、ヤフー〜PFN のオンプレML基盤の取り組み / オンプレML基盤 on Kubernetes 〜PFN、ヤフー〜
PFN のオンプレML基盤の取り組み / オンプレML基盤 on Kubernetes 〜PFN、ヤフー〜Preferred Networks
 
C# ゲームプログラミングはホントにメモリのことに無頓着でいいの?
C# ゲームプログラミングはホントにメモリのことに無頓着でいいの?C# ゲームプログラミングはホントにメモリのことに無頓着でいいの?
C# ゲームプログラミングはホントにメモリのことに無頓着でいいの?京大 マイコンクラブ
 
Humble Object Patternな話
Humble Object Patternな話Humble Object Patternな話
Humble Object Patternな話Hiroto Imoto
 
クロムハウンズにおける 人工知能開発から見るゲームAIの展望 (CEDEC2006)
クロムハウンズにおける人工知能開発から見るゲームAIの展望 (CEDEC2006)クロムハウンズにおける人工知能開発から見るゲームAIの展望 (CEDEC2006)
クロムハウンズにおける 人工知能開発から見るゲームAIの展望 (CEDEC2006)Youichiro Miyake
 
暗号技術の実装と数学
暗号技術の実装と数学暗号技術の実装と数学
暗号技術の実装と数学MITSUNARI Shigeo
 
ゲームAI入門(後半)
ゲームAI入門(後半)ゲームAI入門(後半)
ゲームAI入門(後半)Youichiro Miyake
 
ChatGPTがもたらす未来予測
ChatGPTがもたらす未来予測ChatGPTがもたらす未来予測
ChatGPTがもたらす未来予測Koji Fukuoka
 
Pythonによる黒魔術入門
Pythonによる黒魔術入門Pythonによる黒魔術入門
Pythonによる黒魔術入門大樹 小倉
 
「黒騎士と白の魔王」gRPCによるHTTP/2 - API, Streamingの実践
「黒騎士と白の魔王」gRPCによるHTTP/2 - API, Streamingの実践「黒騎士と白の魔王」gRPCによるHTTP/2 - API, Streamingの実践
「黒騎士と白の魔王」gRPCによるHTTP/2 - API, Streamingの実践Yoshifumi Kawai
 
GPGPU Seminar (PyCUDA)
GPGPU Seminar (PyCUDA)GPGPU Seminar (PyCUDA)
GPGPU Seminar (PyCUDA)智啓 出川
 
Swagger ではない OpenAPI Specification 3.0 による API サーバー開発
Swagger ではない OpenAPI Specification 3.0 による API サーバー開発Swagger ではない OpenAPI Specification 3.0 による API サーバー開発
Swagger ではない OpenAPI Specification 3.0 による API サーバー開発Yahoo!デベロッパーネットワーク
 
RPGにおけるイベント駆動型の設計と実装
RPGにおけるイベント駆動型の設計と実装RPGにおけるイベント駆動型の設計と実装
RPGにおけるイベント駆動型の設計と実装Koji Morikawa
 
コルーチンでC++でも楽々ゲーム作成!
コルーチンでC++でも楽々ゲーム作成!コルーチンでC++でも楽々ゲーム作成!
コルーチンでC++でも楽々ゲーム作成!amusementcreators
 
常識を疑え ゲームの企画書に望まれるものと期待されるもの (HDIfes#3 2014-6-21)
常識を疑え ゲームの企画書に望まれるものと期待されるもの (HDIfes#3 2014-6-21)常識を疑え ゲームの企画書に望まれるものと期待されるもの (HDIfes#3 2014-6-21)
常識を疑え ゲームの企画書に望まれるものと期待されるもの (HDIfes#3 2014-6-21)uehara1974
 
深読みビットコイン (2) コンセンサスの行方
深読みビットコイン (2) コンセンサスの行方深読みビットコイン (2) コンセンサスの行方
深読みビットコイン (2) コンセンサスの行方Kenji Saito
 
セキュリティを楽しむ(CTFとbugbountyの始め方)
セキュリティを楽しむ(CTFとbugbountyの始め方)セキュリティを楽しむ(CTFとbugbountyの始め方)
セキュリティを楽しむ(CTFとbugbountyの始め方)kazkiti
 
実践イカパケット解析α
実践イカパケット解析α実践イカパケット解析α
実践イカパケット解析αYuki Mizuno
 

What's hot (20)

C++ マルチスレッドプログラミング
C++ マルチスレッドプログラミングC++ マルチスレッドプログラミング
C++ マルチスレッドプログラミング
 
ネットワーク ゲームにおけるTCPとUDPの使い分け
ネットワーク ゲームにおけるTCPとUDPの使い分けネットワーク ゲームにおけるTCPとUDPの使い分け
ネットワーク ゲームにおけるTCPとUDPの使い分け
 
Halo2 におけるHFSM(階層型有限状態マシン) 【ビヘイビアツリー解説】
Halo2 におけるHFSM(階層型有限状態マシン)  【ビヘイビアツリー解説】Halo2 におけるHFSM(階層型有限状態マシン)  【ビヘイビアツリー解説】
Halo2 におけるHFSM(階層型有限状態マシン) 【ビヘイビアツリー解説】
 
PFN のオンプレML基盤の取り組み / オンプレML基盤 on Kubernetes 〜PFN、ヤフー〜
PFN のオンプレML基盤の取り組み / オンプレML基盤 on Kubernetes 〜PFN、ヤフー〜PFN のオンプレML基盤の取り組み / オンプレML基盤 on Kubernetes 〜PFN、ヤフー〜
PFN のオンプレML基盤の取り組み / オンプレML基盤 on Kubernetes 〜PFN、ヤフー〜
 
C# ゲームプログラミングはホントにメモリのことに無頓着でいいの?
C# ゲームプログラミングはホントにメモリのことに無頓着でいいの?C# ゲームプログラミングはホントにメモリのことに無頓着でいいの?
C# ゲームプログラミングはホントにメモリのことに無頓着でいいの?
 
Humble Object Patternな話
Humble Object Patternな話Humble Object Patternな話
Humble Object Patternな話
 
クロムハウンズにおける 人工知能開発から見るゲームAIの展望 (CEDEC2006)
クロムハウンズにおける人工知能開発から見るゲームAIの展望 (CEDEC2006)クロムハウンズにおける人工知能開発から見るゲームAIの展望 (CEDEC2006)
クロムハウンズにおける 人工知能開発から見るゲームAIの展望 (CEDEC2006)
 
暗号技術の実装と数学
暗号技術の実装と数学暗号技術の実装と数学
暗号技術の実装と数学
 
ゲームAI入門(後半)
ゲームAI入門(後半)ゲームAI入門(後半)
ゲームAI入門(後半)
 
ChatGPTがもたらす未来予測
ChatGPTがもたらす未来予測ChatGPTがもたらす未来予測
ChatGPTがもたらす未来予測
 
Pythonによる黒魔術入門
Pythonによる黒魔術入門Pythonによる黒魔術入門
Pythonによる黒魔術入門
 
「黒騎士と白の魔王」gRPCによるHTTP/2 - API, Streamingの実践
「黒騎士と白の魔王」gRPCによるHTTP/2 - API, Streamingの実践「黒騎士と白の魔王」gRPCによるHTTP/2 - API, Streamingの実践
「黒騎士と白の魔王」gRPCによるHTTP/2 - API, Streamingの実践
 
GPGPU Seminar (PyCUDA)
GPGPU Seminar (PyCUDA)GPGPU Seminar (PyCUDA)
GPGPU Seminar (PyCUDA)
 
Swagger ではない OpenAPI Specification 3.0 による API サーバー開発
Swagger ではない OpenAPI Specification 3.0 による API サーバー開発Swagger ではない OpenAPI Specification 3.0 による API サーバー開発
Swagger ではない OpenAPI Specification 3.0 による API サーバー開発
 
RPGにおけるイベント駆動型の設計と実装
RPGにおけるイベント駆動型の設計と実装RPGにおけるイベント駆動型の設計と実装
RPGにおけるイベント駆動型の設計と実装
 
コルーチンでC++でも楽々ゲーム作成!
コルーチンでC++でも楽々ゲーム作成!コルーチンでC++でも楽々ゲーム作成!
コルーチンでC++でも楽々ゲーム作成!
 
常識を疑え ゲームの企画書に望まれるものと期待されるもの (HDIfes#3 2014-6-21)
常識を疑え ゲームの企画書に望まれるものと期待されるもの (HDIfes#3 2014-6-21)常識を疑え ゲームの企画書に望まれるものと期待されるもの (HDIfes#3 2014-6-21)
常識を疑え ゲームの企画書に望まれるものと期待されるもの (HDIfes#3 2014-6-21)
 
深読みビットコイン (2) コンセンサスの行方
深読みビットコイン (2) コンセンサスの行方深読みビットコイン (2) コンセンサスの行方
深読みビットコイン (2) コンセンサスの行方
 
セキュリティを楽しむ(CTFとbugbountyの始め方)
セキュリティを楽しむ(CTFとbugbountyの始め方)セキュリティを楽しむ(CTFとbugbountyの始め方)
セキュリティを楽しむ(CTFとbugbountyの始め方)
 
実践イカパケット解析α
実践イカパケット解析α実践イカパケット解析α
実践イカパケット解析α
 

Viewers also liked

ESJ62自由集会・オープンデータからオープンサイエンスへ
ESJ62自由集会・オープンデータからオープンサイエンスへESJ62自由集会・オープンデータからオープンサイエンスへ
ESJ62自由集会・オープンデータからオープンサイエンスへIWASAKI NOBUSUKE
 
Windowsのパケットモニタ作成
Windowsのパケットモニタ作成Windowsのパケットモニタ作成
Windowsのパケットモニタ作成Shinichi Hirauchi
 
日曜プログラマーが
1週間くらいで通信対戦ゲームを作ってみた
日曜プログラマーが
1週間くらいで通信対戦ゲームを作ってみた日曜プログラマーが
1週間くらいで通信対戦ゲームを作ってみた
日曜プログラマーが
1週間くらいで通信対戦ゲームを作ってみたYuusuke Takeuchi
 
Pythonによる非同期プログラミング入門
Pythonによる非同期プログラミング入門Pythonによる非同期プログラミング入門
Pythonによる非同期プログラミング入門Hironori Sekine
 
PHPで大規模ブラウザゲームを開発してわかったこと
PHPで大規模ブラウザゲームを開発してわかったことPHPで大規模ブラウザゲームを開発してわかったこと
PHPで大規模ブラウザゲームを開発してわかったことKentaro Matsui
 
STPとその仲間たち 〜 STP, RSTP, MSTPの概要 〜
STPとその仲間たち 〜 STP, RSTP, MSTPの概要 〜STPとその仲間たち 〜 STP, RSTP, MSTPの概要 〜
STPとその仲間たち 〜 STP, RSTP, MSTPの概要 〜Masahiko Kimoto
 
究極のゲーム用通信プロトコルを探せ!
究極のゲーム用通信プロトコルを探せ!究極のゲーム用通信プロトコルを探せ!
究極のゲーム用通信プロトコルを探せ!Ryosuke Otsuya
 
Tremaとtrema edgeの違い
Tremaとtrema edgeの違いTremaとtrema edgeの違い
Tremaとtrema edgeの違いhiroshi oshiba
 
Open vSwitchソースコードの全体像
Open vSwitchソースコードの全体像 Open vSwitchソースコードの全体像
Open vSwitchソースコードの全体像 Sho Shimizu
 
ニューロンになってみる
ニューロンになってみるニューロンになってみる
ニューロンになってみるKiyoshi SATOH
 
Jpug study-pq 20170121
Jpug study-pq 20170121Jpug study-pq 20170121
Jpug study-pq 20170121Kosuke Kida
 
MySQLやSSDとかの話 後編
MySQLやSSDとかの話 後編MySQLやSSDとかの話 後編
MySQLやSSDとかの話 後編Takanori Sejima
 
Wiresharkの解析プラグインを作る ssmjp 201409
Wiresharkの解析プラグインを作る ssmjp 201409Wiresharkの解析プラグインを作る ssmjp 201409
Wiresharkの解析プラグインを作る ssmjp 201409稔 小林
 
Wireshark だけに頼らない! パケット解析ツールの紹介
Wireshark だけに頼らない! パケット解析ツールの紹介Wireshark だけに頼らない! パケット解析ツールの紹介
Wireshark だけに頼らない! パケット解析ツールの紹介morihisa
 
パケットジェネレータipgenから見るnetmap
パケットジェネレータipgenから見るnetmapパケットジェネレータipgenから見るnetmap
パケットジェネレータipgenから見るnetmapfurandon_pig
 
Advanced technic for OS upgrading in 3 minutes
Advanced technic for OS upgrading in 3 minutesAdvanced technic for OS upgrading in 3 minutes
Advanced technic for OS upgrading in 3 minutesHiroshi SHIBATA
 
ポコロンダンジョンズとリアルタイム通信 -クライアント編-
ポコロンダンジョンズとリアルタイム通信 -クライアント編-ポコロンダンジョンズとリアルタイム通信 -クライアント編-
ポコロンダンジョンズとリアルタイム通信 -クライアント編-Suguru Shirai
 

Viewers also liked (20)

ESJ62自由集会・オープンデータからオープンサイエンスへ
ESJ62自由集会・オープンデータからオープンサイエンスへESJ62自由集会・オープンデータからオープンサイエンスへ
ESJ62自由集会・オープンデータからオープンサイエンスへ
 
Windowsのパケットモニタ作成
Windowsのパケットモニタ作成Windowsのパケットモニタ作成
Windowsのパケットモニタ作成
 
日曜プログラマーが
1週間くらいで通信対戦ゲームを作ってみた
日曜プログラマーが
1週間くらいで通信対戦ゲームを作ってみた日曜プログラマーが
1週間くらいで通信対戦ゲームを作ってみた
日曜プログラマーが
1週間くらいで通信対戦ゲームを作ってみた
 
Pythonによる非同期プログラミング入門
Pythonによる非同期プログラミング入門Pythonによる非同期プログラミング入門
Pythonによる非同期プログラミング入門
 
PHPで大規模ブラウザゲームを開発してわかったこと
PHPで大規模ブラウザゲームを開発してわかったことPHPで大規模ブラウザゲームを開発してわかったこと
PHPで大規模ブラウザゲームを開発してわかったこと
 
LLDP機能の概要
LLDP機能の概要LLDP機能の概要
LLDP機能の概要
 
カーネルモジュールプログラミング超入門 #1(仮)
カーネルモジュールプログラミング超入門 #1(仮)カーネルモジュールプログラミング超入門 #1(仮)
カーネルモジュールプログラミング超入門 #1(仮)
 
STPとその仲間たち 〜 STP, RSTP, MSTPの概要 〜
STPとその仲間たち 〜 STP, RSTP, MSTPの概要 〜STPとその仲間たち 〜 STP, RSTP, MSTPの概要 〜
STPとその仲間たち 〜 STP, RSTP, MSTPの概要 〜
 
究極のゲーム用通信プロトコルを探せ!
究極のゲーム用通信プロトコルを探せ!究極のゲーム用通信プロトコルを探せ!
究極のゲーム用通信プロトコルを探せ!
 
Tremaとtrema edgeの違い
Tremaとtrema edgeの違いTremaとtrema edgeの違い
Tremaとtrema edgeの違い
 
Open vSwitchソースコードの全体像
Open vSwitchソースコードの全体像 Open vSwitchソースコードの全体像
Open vSwitchソースコードの全体像
 
ニューロンになってみる
ニューロンになってみるニューロンになってみる
ニューロンになってみる
 
Jpug study-pq 20170121
Jpug study-pq 20170121Jpug study-pq 20170121
Jpug study-pq 20170121
 
MySQLやSSDとかの話 後編
MySQLやSSDとかの話 後編MySQLやSSDとかの話 後編
MySQLやSSDとかの話 後編
 
Wiresharkの解析プラグインを作る ssmjp 201409
Wiresharkの解析プラグインを作る ssmjp 201409Wiresharkの解析プラグインを作る ssmjp 201409
Wiresharkの解析プラグインを作る ssmjp 201409
 
Wireshark だけに頼らない! パケット解析ツールの紹介
Wireshark だけに頼らない! パケット解析ツールの紹介Wireshark だけに頼らない! パケット解析ツールの紹介
Wireshark だけに頼らない! パケット解析ツールの紹介
 
パケットジェネレータipgenから見るnetmap
パケットジェネレータipgenから見るnetmapパケットジェネレータipgenから見るnetmap
パケットジェネレータipgenから見るnetmap
 
CPUに関する話
CPUに関する話CPUに関する話
CPUに関する話
 
Advanced technic for OS upgrading in 3 minutes
Advanced technic for OS upgrading in 3 minutesAdvanced technic for OS upgrading in 3 minutes
Advanced technic for OS upgrading in 3 minutes
 
ポコロンダンジョンズとリアルタイム通信 -クライアント編-
ポコロンダンジョンズとリアルタイム通信 -クライアント編-ポコロンダンジョンズとリアルタイム通信 -クライアント編-
ポコロンダンジョンズとリアルタイム通信 -クライアント編-
 

Similar to 60分でわかるソケットプログラミング

Linuxでソフトシンセを作って動かす
Linuxでソフトシンセを作って動かすLinuxでソフトシンセを作って動かす
Linuxでソフトシンセを作って動かすMasahiko Kimoto
 
つくってドヤると楽しい
つくってドヤると楽しいつくってドヤると楽しい
つくってドヤると楽しいJunichi Akita
 
コンテナセキュリティにおける権限制御(OCHaCafe5 #3 Kubernetes のセキュリティ 発表資料)
コンテナセキュリティにおける権限制御(OCHaCafe5 #3 Kubernetes のセキュリティ 発表資料)コンテナセキュリティにおける権限制御(OCHaCafe5 #3 Kubernetes のセキュリティ 発表資料)
コンテナセキュリティにおける権限制御(OCHaCafe5 #3 Kubernetes のセキュリティ 発表資料)NTT DATA Technology & Innovation
 
AWS Security JAWS 経済的にハニーポットのログ分析をするためのベストプラクティス?
AWS Security JAWS 経済的にハニーポットのログ分析をするためのベストプラクティス?AWS Security JAWS 経済的にハニーポットのログ分析をするためのベストプラクティス?
AWS Security JAWS 経済的にハニーポットのログ分析をするためのベストプラクティス?Masamitsu Maehara
 
サマータイムとうるう秒と2038年問題
サマータイムとうるう秒と2038年問題サマータイムとうるう秒と2038年問題
サマータイムとうるう秒と2038年問題UEHARA, Tetsutaro
 
Pub/Sub model, msm, and asio
Pub/Sub model, msm, and asioPub/Sub model, msm, and asio
Pub/Sub model, msm, and asioTakatoshi Kondo
 
タミヤのカムロボを改造中 micro:bit編
タミヤのカムロボを改造中 micro:bit編タミヤのカムロボを改造中 micro:bit編
タミヤのカムロボを改造中 micro:bit編Yasuhisa Hironaka
 
道具としての半導体設計:Lチカを題材として
道具としての半導体設計:Lチカを題材として道具としての半導体設計:Lチカを題材として
道具としての半導体設計:Lチカを題材としてJunichi Akita
 
JTF2020 クロスコンパイルだけが能ではない組み込みLinuxシステムのCI/CDインフラ構築
JTF2020 クロスコンパイルだけが能ではない組み込みLinuxシステムのCI/CDインフラ構築JTF2020 クロスコンパイルだけが能ではない組み込みLinuxシステムのCI/CDインフラ構築
JTF2020 クロスコンパイルだけが能ではない組み込みLinuxシステムのCI/CDインフラ構築yaegashi
 
C++ in Embedded Systems
C++ in Embedded SystemsC++ in Embedded Systems
C++ in Embedded Systemskikairoya
 
MINCS – containers in the shell script
MINCS – containers in the shell scriptMINCS – containers in the shell script
MINCS – containers in the shell scriptMasami Hiramatsu
 
組み込みシステムのセキュリティ
組み込みシステムのセキュリティ組み込みシステムのセキュリティ
組み込みシステムのセキュリティFFRI, Inc.
 
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭するCEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭するYoshifumi Kawai
 
30日でできない!コンピューター自作入門 - カーネル/VM探検隊@つくば
30日でできない!コンピューター自作入門 - カーネル/VM探検隊@つくば30日でできない!コンピューター自作入門 - カーネル/VM探検隊@つくば
30日でできない!コンピューター自作入門 - カーネル/VM探検隊@つくばHirotaka Kawata
 
MaxScaleを触ってみた
MaxScaleを触ってみたMaxScaleを触ってみた
MaxScaleを触ってみたFujishiro Takuya
 
Cell/B.E. プログラミング事始め
Cell/B.E. プログラミング事始めCell/B.E. プログラミング事始め
Cell/B.E. プログラミング事始めYou&I
 
A story of porting OpenBSD/luna88k
A story of porting OpenBSD/luna88kA story of porting OpenBSD/luna88k
A story of porting OpenBSD/luna88kKenji Aoyama
 

Similar to 60分でわかるソケットプログラミング (20)

Linuxでソフトシンセを作って動かす
Linuxでソフトシンセを作って動かすLinuxでソフトシンセを作って動かす
Linuxでソフトシンセを作って動かす
 
つくってドヤると楽しい
つくってドヤると楽しいつくってドヤると楽しい
つくってドヤると楽しい
 
コンテナセキュリティにおける権限制御(OCHaCafe5 #3 Kubernetes のセキュリティ 発表資料)
コンテナセキュリティにおける権限制御(OCHaCafe5 #3 Kubernetes のセキュリティ 発表資料)コンテナセキュリティにおける権限制御(OCHaCafe5 #3 Kubernetes のセキュリティ 発表資料)
コンテナセキュリティにおける権限制御(OCHaCafe5 #3 Kubernetes のセキュリティ 発表資料)
 
AWS Security JAWS 経済的にハニーポットのログ分析をするためのベストプラクティス?
AWS Security JAWS 経済的にハニーポットのログ分析をするためのベストプラクティス?AWS Security JAWS 経済的にハニーポットのログ分析をするためのベストプラクティス?
AWS Security JAWS 経済的にハニーポットのログ分析をするためのベストプラクティス?
 
Prosym2012
Prosym2012Prosym2012
Prosym2012
 
Android gameprogramming
Android gameprogrammingAndroid gameprogramming
Android gameprogramming
 
サマータイムとうるう秒と2038年問題
サマータイムとうるう秒と2038年問題サマータイムとうるう秒と2038年問題
サマータイムとうるう秒と2038年問題
 
Pub/Sub model, msm, and asio
Pub/Sub model, msm, and asioPub/Sub model, msm, and asio
Pub/Sub model, msm, and asio
 
タミヤのカムロボを改造中 micro:bit編
タミヤのカムロボを改造中 micro:bit編タミヤのカムロボを改造中 micro:bit編
タミヤのカムロボを改造中 micro:bit編
 
道具としての半導体設計:Lチカを題材として
道具としての半導体設計:Lチカを題材として道具としての半導体設計:Lチカを題材として
道具としての半導体設計:Lチカを題材として
 
JTF2020 クロスコンパイルだけが能ではない組み込みLinuxシステムのCI/CDインフラ構築
JTF2020 クロスコンパイルだけが能ではない組み込みLinuxシステムのCI/CDインフラ構築JTF2020 クロスコンパイルだけが能ではない組み込みLinuxシステムのCI/CDインフラ構築
JTF2020 クロスコンパイルだけが能ではない組み込みLinuxシステムのCI/CDインフラ構築
 
C++ in Embedded Systems
C++ in Embedded SystemsC++ in Embedded Systems
C++ in Embedded Systems
 
MINCS – containers in the shell script
MINCS – containers in the shell scriptMINCS – containers in the shell script
MINCS – containers in the shell script
 
組み込みシステムのセキュリティ
組み込みシステムのセキュリティ組み込みシステムのセキュリティ
組み込みシステムのセキュリティ
 
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭するCEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
 
Introduction of FPGA
Introduction of FPGAIntroduction of FPGA
Introduction of FPGA
 
30日でできない!コンピューター自作入門 - カーネル/VM探検隊@つくば
30日でできない!コンピューター自作入門 - カーネル/VM探検隊@つくば30日でできない!コンピューター自作入門 - カーネル/VM探検隊@つくば
30日でできない!コンピューター自作入門 - カーネル/VM探検隊@つくば
 
MaxScaleを触ってみた
MaxScaleを触ってみたMaxScaleを触ってみた
MaxScaleを触ってみた
 
Cell/B.E. プログラミング事始め
Cell/B.E. プログラミング事始めCell/B.E. プログラミング事始め
Cell/B.E. プログラミング事始め
 
A story of porting OpenBSD/luna88k
A story of porting OpenBSD/luna88kA story of porting OpenBSD/luna88k
A story of porting OpenBSD/luna88k
 

60分でわかるソケットプログラミング

  • 1. (c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6 60分でわかるソケットプログラミン グ 60分でわかるソケットプログラミン グ 木本雅彦 <kimoto@soum.co.jp> <kimoto@ohnolab.org> 株式会社創夢 第三開発部 シニアプロジェクトマネージャ 初版:2010年4月作成、改定版:2015年3月作成
  • 2. (c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6 創夢とはどういう会社か UNIXとTCP/IPネットワークに強い会社 全員がUNIXに詳しい 全員がIPに詳しい ということは → 全社員がネットワークプログラミングくら い出来るよね!? ということで、60分レクチャーです 1/47
  • 3. (c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6 この発表での前提条件 C言語でのプログラミングはできる system call programming file I/O basics TCP/IPの基礎は理解している OSI階層モデル IPアドレス、ヘッダの構造など 2/47
  • 4. (c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6 IPというプロトコルについて IP = InternetProtocol はじめに: ホストにはIPアドレスがついているらしいぜ (以下略。知らない人は自力で勉強してください) 3/47
  • 5. (c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6 TCPとUDPというプロトコル TCP: Transmission Control Protocol 送達確認(ACK)の利用による信頼性のある通信 輻輳制御による「フェアな」通信量の制御 UDP: User Datagram Protocol 信頼性のない通信 パケット単位でデータを投げるだけ 4/47
  • 6. (c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6 port番号 TCP, UDPで用いる通信口の番号 符号なし16bit 通信相手のアプリケーションを同定する 5/47
  • 7. (c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6 well-known portとephemeral port well-known port 代表的なサービスに割り当てられた番号 0 - 1023 IANAが管理している ephemeral port 使い捨てポート RFCでのdynamic port: 49152〜65535 Linuxの実装: 32768〜61000 古いBSDの実装: 1024〜4999 6/47
  • 8. (c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6 一応IPv6について、ひとこと 次世代インターネットプロトコル といいつつ、すでに実用化されている IPアドレスが128bitに拡張されたという一点がもっとも 重要 アドレスの自動設定 マルチキャストの積極的な利用 7/47
  • 9. (c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6 UNIXのプロセス間通信 pipe 双方向パイプ FIFO 共有メモリ(SYSV由来) セマフォ(SYSV由来) signal socket(BSD由来) 8/47
  • 10. (c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6 socket 4.2BSDで導入されたTCP/IPの抽象化および実装 通信路の片方の末端を指し示す ファイルデスクリプタで表される →ネットワーク通信をファイルI/Oと同様に記述できる 9/47
  • 11. (c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6 余談:socketという敗北 4.2BSDでsocketが導入されたのは、従来のUNIXの ようにファイルシステム上にネットワークI/Oをマッピングで きなかったため 主に性能上の理由 これが後々まで影響を及ぼす 例:jailやDocker(コンテナ型仮想化)において、ネットワークの制約の ための枠組みが別途必要になる 10/47
  • 12. (c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6 サーバクライアントモデル ネットワーク通信のモデル化の一つ vs Peer to Peer サーバ サービスを提供する側 要求を待って処理した結果を返す クライアント サービスを利用する側 サーバに接続し要求を出し処理結果を受け取る 11/47
  • 13. (c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6 サーバクライアントの通信の流れ 12/47
  • 14. (c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6 サーバ側の処理の流れ socket(2)でsocketを作る bind(2)でsocketに待受アドレスとポートを指定する listen(2)で待受開始 select(2)で複数ソケットのイベントループを回す 接続があったらaccept(2)で受信して通信用ソケット を得る read(2), write(2)で送受信 13/47
  • 15. (c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6 socket(2) ソケットを作成するsystemcall ソケットを表すファイルデスクリプタを返す int socket(int domain, int type, int protocol); domain: PF_INET, PF_INET6, .... type: SOCK_STREAM, SOCK_DGRAM, .. protocol: IPPROTO_IP, ... 14/47
  • 16. (c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6 bind(2) ソケットに名前をつける 名前とは: IPアドレス ポート番号 int bind(int s, const struct sockaddr *addr, socklen_t addrlen); 第2引数で名前=アドレスを指定する 15/47
  • 17. (c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6 listen(2) 接続を待ち受ける int listen(int s, int backlog); backlogは最大保留数 16/47
  • 18. (c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6 accept(2) TCPの接続を受けつけ、dynamic portを割り当てる int accept(int s, struct sockaddr * restrict addr, socklen_t * restrict addrlen); 17/47
  • 19. (c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6 イベントドリブン型プログラミング 外部からのイベントを契機に処理を駆動するプログラミ ングモデル イベント待ち受け イベント受信 ディスパッチ if文の羅列による分岐 ハンドラ/ジャンプテーブル タイマ処理と合わせて擬似スレッドも実現できる 18/47
  • 20. (c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6 select(2)システムコール fd_set: fdの集合(ビットマップ) read/write/errでチェックするfdを指定(複数可) selectで待つ fd_setにイベントが発生したsocketのfdがセットされる 19/47
  • 21. (c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6 典型的なselect loop sock = accept(....); for (;;) { FD_ZERO(&fds); FD_SET(sock, &fds); result = select(getdtablesize(),&fds,NULL,NULL, NULL); if (FD_ISSET(sock,&fds)) { **** read from socket ****** } } 20/47
  • 22. (c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6 多重待受のselect loop listenしているポートもselectの対象にする listen(lsock, ....); for (;;) { FD_ZERO(&fds); FD_SET(lsock, &fds); if (sock >= 0) {FD_SET(sock, &fds);} result = select(getdtablesize(),&fds,NULL,NULL, NULL); if (FD_ISSET(lsock,&fds)) { sock = accept(lsock, ...); continue; } if (sock >= 0 && FD_ISSET(sock,&fds)) { **** read from socket ****** } } 21/47
  • 23. (c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6 クライアント側の処理の流れ socket(2)でsocketを作る bind(2)でsocketに通信先アドレスとポートを指定す る connect(2)で接続する read(2), write(2)で送受信 22/47
  • 24. (c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6 connect(2) ソケット経由で接続開始する int connect(int s, const struct sockaddr *name, socklen_t namelen); 23/47
  • 25. (c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6 readn, writen socketからの読み書きは1度のread/writeで完了す る保証がない 指定した長さが完了するまでread/writeを繰り返す 必要がある readn() / writen() 関数を使う cf. Stevens' UNIX Network Programming ただしブロックしてしまうので注意が必要 24/47
  • 26. (c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6 sample code of writen: int writen(int fd,char *ptr,size_t size) { int i; while(size > 0) { if ((i = write(fd,ptr,size)) < 0) return i; ptr += i; size -= i; } return size; } 25/47
  • 27. (c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6 UDPとTCPのプログラミングの違い UDPクライアントはbindしなくていい(してもいい) UDPクライアントはconnectしなくていい(してもいい) UDPはsendto(2)/recvfrom(2)で相手を指定して 送受信できる connectしていればread/writeでもよい 26/47
  • 28. (c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6 文字列からIPアドレスを得る古い方法 inet_aton IPアドレスの文字列を数値に変換する gethostbyname ホスト名からIPアドレスを得る gethostbyname2 AddressFamilyを指定してホスト名からIPアドレスを得る getservbyname サービス名からポート番号を得る 27/47
  • 29. (c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6 IPアドレスを得る新しい方法 getaddrinfoを使ったクライアントの例 getaddrinfo(peer, buf, &hints, &res0)); s = -1; for (res = res0; res; res = res->ai_next) { s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); if (s < 0) continue; connect(s, res->ai_addr, res->ai_addrlen); break; } 28/47
  • 30. (c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6 ソケットが使っているアドレスを得る方法 getsockname ソケットの自分側のsockaddrを得る getpeername ソケットの相手側のsockaddrを得る 29/47
  • 31. (c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6 poll, libevent selectを使った実装は重くなる fdごとにif文でチェックするため poll(struct pollfd fds[], nfds_t nfds, int timeout); チェックのコストが低い libevent イベントハンドラを記述するだけ socket以外のイベントも監視できる 30/47
  • 32. (c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6 タイマ処理 タイマ割り込みによる定期的な処理 alarm(unsigned int seconds); setitimer(int which, .....); selectのtimeoutを用いてタイマ処理を実装すること もある 31/47
  • 33. (c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6 selectとsignal signalを受信してselectを抜ける場合があるので注 意 タイマ割り込みなど selectがエラーで終了したら、errnoの値を調べる必要がある do { result = select(getdtablesize(),&fds,&wfds,NULL, &tv2); } while((result < 0) && (errno == EINTR)); 32/47
  • 34. (c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6 bind: address already in use bindしようとしたら、他のプロセスが既にportを使って いる プロセスが異常終了した後、サーバーを再起動すると 出ることがある setsockopt(s, SOL_SOCKET, SO_REUSEPORT, (char *)&sockopt, sizeof(sockopt)); 33/47
  • 35. (c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6 setsockopt socketの動作を設定する SO_REUSEADDR enables local address reuse SO_REUSEPORT enables duplicate address and port bindings SO_KEEPALIVE enables keep connections alive SO_DONTROUTE enables routing bypass for outgoing messages SO_LINGER linger on close if data present ..... 34/47
  • 36. (c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6 non blocking socket 複数のサーバに同時に非同期にconnectしたい場合 サーバとクライアントを兼ねている場合 e.g. bgpd, P2P application connectでblockしない f = fcntl(s, F_GETFL); fcntl(s, F_SETFL, f | O_NONBLOCK); 35/47
  • 37. (c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6 自分のIPアドレスを得る方法 ダメな例 gethostname() → gethostbyname() 多くの場合は127.0.0.1になる 実用的な例 UDP socketを作る 遠くのアドレスに向けてconnectする getsocknameする ただし経路がない場合はこの方法は使えない 36/47
  • 38. (c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6 struct sockaddr 異なるプロトコルのアドレスを格納するための構造体 struct sockaddr { unsigned char sa_len; /* total length */ sa_family_t sa_family; /* address family */ char sa_data[14]; /* actually longer; address value */ }; OSの違いによるsa_lenの有無に注意が必要 領域を確保するためには、sockaddr_storageを使う 37/47
  • 39. (c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6 UNIX domain socket いわゆる名前付きパイプ 単一ホスト内の通信に使う PF_UNIX or PF_LOCAL bindする時にパス名を使う 実際にファイルが作成される e.g. try, ls -la /tmp/ 38/47
  • 40. (c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6 socketpair(2) 名前なしパイプ 連結した二つのsocketを返す パイプと同様に使える 双方向に通信可能 39/47
  • 41. (c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6 コネクション切断を識別する selectでreadableなのにreadすると0byte → connectionが切れている この処理をしないとselect loopが回り続けるので注 意 40/47
  • 42. (c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6 inetd: Internet super daemon クライアントからの待ち受けをinetdが行う 接続があったら、プロセスに引き渡す socketがプロセスの標準入出力に割り当てられる 標準入出力のI/Oだけでサーバが記述できる 41/47
  • 43. (c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6 daemon化するということ daemon化には決まった手順がある 2度forkした後、途中のprocessを終了させ、initの子供になる 標準入出力を/dev/nullに割り当てる 制御端末を切り離す 通常はroot directoryに移動する see daemon(3) 42/47
  • 44. (c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6 raw socket IPペイロードを直接入出力できる ICMP, OSPFなどで使われている see ping root権限が必要 よって、pingはsetuidされている 43/47
  • 45. (c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6 BPF: Berkley Packet Filter 生のEthernet Frameを送受信できる /dev/bpf?をopenする ioctlでインタフェースを割り当てる readするとBPFヘッダがついてくる 複数のパケットが読める場合もある writeするとそのままEthernet I/Fに出て行く read時にfilterを記述できる filterは「状態マシン」 44/47
  • 46. (c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6 Packet Socket : LinuxでL2のパケットを 送受信する方法 PF_PACKET, SOCK_RAWを指定してsocketを作 る L2のパケットを直接送受信できる インタフェースはbind()で割り当てる 簡単なフィルタはあるが、主にPPPoE用と思われる 送受信はread()/write()で行う sock = socket(PF_PACKET, SOCK_RAW, 0); 45/47
  • 47. (c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6 パケット構造設計の注意点 独自でバイナリ形式のプロトコルを設計する場合 バージョン番号はつけること パケットの長さは先頭部分で明示したほうがよい メモリ領域の確保のため ヘッダとボディとに分けるとよい ボディはTLV(Type, Length, Value)でいいかもしれない 46/47
  • 48. (c) Masahiko KIMOTO, Ph.D. - http://www.earthlight.jp/ Powered by Rabbit 2.1.6 Where should you start from? inetd 1 session server and client multi-session server and more... 47/47