スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

Tag:スポンサー広告 

【C】UnixDomainにおけるプロセス間の通信

サーバとクライアントにおける通信を理解するためのプログラミング例

通常サーバとクライアントの通信というとWebサーバとWebブラウザとの通信を思い浮かべてしまいます。

これをもう少し噛み砕くと「Webサーバの役目を果たすプログラム」と「Webブラウザの役目を果たすプログラム」との通信になります。

つまり「プロセス間における通信」と持って行くことができそう。

プロセス間の通信の方法の一つに「ソケット通信」というものがあります。
ソケットに関して詳しくはググって欲しいのですが、簡単に説明するとプログラム同士が通信するためのインターフェースですね。

電気ケーブルとかのソケットと考えるとイメージ付けやすいかも知れません。

今回はWebサーバとWebブラウザのようなインターネットを通してのプロセス間の通信ではなくて、

同じOS内でのプロセス間の通信を考えてみます。

これを

「UnixDomainにおけるプロセス間の通信」

といいます。

あんまり目立たないけどコマンドを打たなくてもOS内ではいろんなプログラムが動いてて、それらがたくさん通信してますよね。

今回はシンプルに簡単なメッセージをやり取りするサーバ、クライアントモデルで作ってみました。

あるファイルをソケットとし、そのソケットを通してメッセージのやり取りを行う
今回の例ではserver_socketというファイルをソケットとして通して通信を行う

ただし今回は1対1の通信です。これをforkしたりすれば並列でメッセージの処理を行うことも可能ですね

サーバプログラム
#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<sys/un.h>


#define BUFFSIZE 256
#define ERR -1


int main(int argc, char *argv[])
{
    int socket_fd;//ソケット用のファイルディスクリプタ
    int accept_fd;
    struct sockaddr_un server;//サーバ構造体
    struct sockaddr_un client;//クライアント構造体
    int fromlen;
    char buf[BUFFSIZE];
    int message_len;

    if(argc != 2){
        printf("Usage: [command_name] [response message]\n");
        exit(1);
    }

    if( (socket_fd = socket(PF_UNIX, SOCK_STREAM, 0)) == ERR){
        perror("server: socket");
        exit(1);
    }

    bzero((char * )&server, sizeof(server));
    //プロトコルファミリをunixに指定(UNIXドメイン)
    server.sun_family = PF_UNIX;

    bcopy("server_socket", server.sun_path, sizeof("server_socket"));

    unlink("server_socket");

    if(bind(socket_fd, (struct sockaddr *)&server, sizeof(server)) == ERR){
        perror("server: bind");
        exit(1);
    }

    if(listen(socket_fd, 5) == ERR){//5つのリクエストを受けます
        perror("server: listen");
        exit(1);
    }

    bzero((char *)&client, sizeof(client));
    fromlen = sizeof(client);

    if((accept_fd = accept(socket_fd, (struct sockaddr *)&client, &fromlen)) == ERR){
        perror("server: accept");
        exit(1);
    }

    printf("\nconnect request from: %s\n", client.sun_path);

    if(read(accept_fd, buf, BUFFSIZE) == ERR){
        perror("server: read");
        exit(1);
    }

  printf("\n<SERVER> message from client : %s\n", buf);

    message_len = strlen(argv[1]) + 1;
    if(write(accept_fd, argv[1], message_len) == ERR){
        //クライアントとのインターフェースとなるファイルディスクリプタを指定してメッセージのやり取り
        perror("server: write");
        exit(1);
    }

    close(accept_fd);
    close(socket_fd);

    exit(0);
}


クライアントプログラム
#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<sys/un.h>

#define BUFFSIZE 256
#define ERR -1

void main(int argc, char *argv[])
{
    int socket_fd;
    struct sockaddr_un server;
    struct hostent *hp;
    char buf[BUFFSIZE];
    int message_len;

    if(argc != 2){
        printf("Usage: [command] [message]\n");
        exit(1);
    }

    if( ( socket_fd = socket(PF_UNIX, SOCK_STREAM, 0)) == ERR){
        perror("client: socket");
        exit(1);
    }

    bzero((char *)&server, sizeof(server));
    server.sun_family = PF_UNIX;
    bcopy("server_socket", server.sun_path, sizeof("server_socket"));

    if(connect(socket_fd, (struct sockaddr *)&server, sizeof(server)) == ERR){
        perror("client: connect");
        exit(1);
    }

    message_len = strlen(argv[1]) + 1;

    if(write(socket_fd, argv[1], message_len) == ERR){
        perror("client: write");
        exit(1);
    }

    if(read(socket_fd, buf, BUFFSIZE) == ERR){
        perror("client: read");
        exit(1);
    }

    printf("\n<CLIENT>message from server : %s\n\n", buf);

    close(socket_fd);

    exit(0);
}


作ってみて

「ソケット」という「ファイル」に対して、read,writeというシステムコールが使えた(Unixはすべてをファイルとして扱う思想そのもの)

これは通常のファイルに読み書きする感覚で通信相手のプロセスにデータを送ることができるということ。

次はIPを使ったINETドメインについて書きます。
スポンサーサイト
テーマ : コンピュータ関連
ジャンル : コンピュータ

Tag:C/C++  Trackback:0 comment:0 

Comment

comment form
(編集・削除用):
管理者にだけ表示を許可
プロフィール

6rats

Author:6rats
こんにちは、ITベンチャーで働くエンジニアです
主に自分の周りで起きた技術的なことをメモとして書き残して行きます。
Android以外にもRuby/Ruby on RailsやFuelPHPなどなどたまにやります。基本的なスタンスとしては興味があるもしくは必要になったらいろんなことにチャレンジします。
最近はiOSアプリ開発を始めています。

購読
follow us in feedly
個人プロダクト

Androidアプリ

Twitterクライアント

Webアプリケーション

EcPriceWatch(Amazon価格の推移を計測、最安値を知らせるサービス)
Google AdSense
ブログ村
にほんブログ村 IT技術ブログへ
にほんブログ村
ブロとも申請フォーム

この人とブロともになる

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。