株式会社アイズ・ソフトウェア

/~eyes-software-co-jp/A1A2
お問い合わせ |  情報セキュリティへの取組について情報セキュリティ方針個人情報保護方針) |  ブログ

BLOG 社員ブログ

C

ソケット通信サンプル

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;
}
============ ここまで ============

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

  • Category:
  • タグ:C
  • Author:eyes-software-co-jp