ソケット通信サンプル


C言語でのソケット通信の手順について説明します。

サーバー側
ソケット通信において、通信先からの接続を待つ側がサーバーとなります。

1.socket()にてソケットを生成する。
2.getservbyname()にてポート情報を得る。
  これは/etc/servicesをサービス名で検索し、ポート番号を求めるための手順であり、ポート番号を決め打ちする場合は必要ない。
  ポート番号を決め打ちする場合には、bind()の引数のsockaddr_in構造体に addr.sin_port = htons( 50000 ); の様に、ポート番号をネットワークバイトオーダーで設定する。
3.bind()にてソケットにポート番号及びIPアドレスを設定する
4.listen()にて接続を待つ
5.accept()にて接続を確立する。
6.以後、acceptにて取得したソケットにてソケットの送受信を行う。
  先に生成した接続待ちの為のソケットと、acceptで取得した通信用のソケットの2つのソケットがあることに注意すること。

クライアント側
ソケット通信において、サーバーへ接続する側がクライアントとなります。

1.socket()にてソケットを生成する。
2.gethostbyname()にてホスト情報を得る。
  これは/etc/hostsをホスト名で検索し、IPアドレスを求めるための手順であり、IPアドレスを決め打ちする場合は必要ない。
  IPアドレスを決め打ちする場合には、connect()の引数のsockaddr_in構造体に sin.sin_addr.s_addr = inet_addr(“127.0.0.1”); の様にIPアドレスを設定する。
3.getservbyname()にてポート情報を得る。
4.connect()にてサーバー側に接続する
5.以後、connectしたソケットにてソケットの送受信を行う。

========== サーバー側 ============

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>

int main(int argc, char** argv)
{
    int fd;
    int fd2;
    struct servent *serv;
    struct sockaddr_in addr;
    socklen_t len = sizeof(struct sockaddr_in);
    struct sockaddr_in from_addr;
    char buf[2048];

    // 受信バッファを初期化する
    memset(buf, 0, sizeof(buf));
    // ソケットを作成する
    if (( fd = socket(AF_INET, SOCK_STREAM, 0 )) < 0 ) {
        fprintf( stdout, "socket error : fd = %d\n", fd );
        return -1;
    }

    serv = getservbyname( "vboxd", "tcp" );
    if ( !serv ){
        close( fd );
        return -1;
    }
    // IPアドレス、ポート番号を設定
    addr.sin_family = AF_INET;
    addr.sin_port = serv->s_port;
    addr.sin_addr.s_addr = INADDR_ANY;
    // バインドする
    if ( bind( fd, (struct sockaddr *)&addr, sizeof(addr)) < 0 ) {
        fprintf( stdout, "bind error\n" );
        return -1;
    }
    // パケット受信待ち状態とする。待ちうけるコネクト要求は1
    if ( listen( fd, 1 ) < 0 ) {
        fprintf( stdout, "listen error\n" );
        return -1;
    }
    // クライアントからの接続を確立する
    if (( fd2 = accept(fd, (struct sockaddr *)&from_addr, &len )) < 0 ) {
        fprintf( stdout, "accept error : fd2 = %d\n", fd2 );
        return -1;
    }
    // パケット受信
    if ( recv( fd2, buf, sizeof(buf), 0 ) < 0 ) {
        fprintf( stdout, "recv");
        return -1;
    }
    // パケット送受信用ソケットクローズ
    close(fd2);
    // 接続要求待ち受け用ソケットクローズ
    close(fd);
    // 受信データの出力
    fprintf( stdout, "%s\n", buf );
    return 0;
}

========== クライアント側 ==========

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>

int main(int argc, char** argv)
{
    int fd;
    struct hostent *info;
    struct servent *serv;
    struct sockaddr_in addr;
    char buff[2048];

    // IPv4 TCP のソケットを作成する
    if((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        fprintf( stdout, "socket error\n" );
        return -1;
    }
    // hostsからホスト情報をを読み出す
    info = gethostbyname("localhost");
    if ( !info ){
        close( fd );
        fprintf( stdout, "gethostbyname error\n" );
        return -1;
    }
    serv = getservbyname( "vboxd", "tcp" );
    if ( !serv ){
        close( fd );
        fprintf( stdout, "getservbyname error\n" );
        return -1;
    }
    // 送信先アドレスとポート番号を設定する
    addr.sin_family = AF_INET;
    addr.sin_port = serv->s_port;
    addr.sin_addr = *(struct in_addr *)(info->h_addr_list[0]);
    // サーバ接続
    connect(fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in));
    sprintf( buff, "Thi is send Message" );
    // パケットを送信
    if ( send( fd, buff, strlen(buff), 0 ) < 0 ) {
        close( fd );
        fprintf( stdout, "send error\n" );
        return -1;
    }
    close(fd);
    return 0;
}

============ ここまで ============

上記サンプルプログラムを使用して発生した障害,問題などに関して,プログラムの作者および(株)アイズ・ソフトウェアは一切の責任を負いません。
使用はご自身の責任で行ってください。


関連記事

TOP
CONTACT ACCESS LINE CALL