サンプル集  >  LinuxC  >  通信(サーバー側)
通信(サーバー側)
2013/11/25

通信プログラムのサーバー側です。

◆環境
OS Linux obsax3 3.0.6 #1 SMP Fri Nov 16 11:53:45 JST 2012 armv7l GNU/Linux
gcc 4.4.5 (Debian 4.4.5-8)

クライアントからの接続後、メッセージを送信するかしないかを選択できるようにしました。

LC112Server.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: 
 32: 
 33: 
 34: 
 35: 
 36: 
 37: 
 38: 
 39: 
 40: 
 41: 
 42: 
 43: 
 44: 
 45: 
 46: 
 47: 
 48: 
 49: 
 50: 
 51: 
 52: 
 53: 
 54: 
 55: 
 56: 
 57: 
 58: 
 59: 
 60: 
 61: 
 62: 
 63: 
 64: 
 65: 
 66: 
 67: 
 68: 
 69: 
 70: 
 71: 
 72: 
 73: 
 74: 
 75: 
 76: 
 77: 
 78: 
 79: 
 80: 
 81: 
 82: 
 83: 
 84: 
 85: 
 86: 
 87: 
 88: 
 89: 
 90: 
 91: 
 92: 
 93: 
 94: 
 95: 
 96: 
 97: 
 98: 
 99: 
100: 
101: 
102: 
103: 
104: 
105: 
106: 
107: 
108: 
109: 
110: 
111: 
112: 
113: 
114: 
115: 
116: 
117: 
118: 
119: 
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include "outputLog.h"

int main()
{
    outputLog( "SV""LC112Server START\n" );

    int srcSocket;    // 自分
    int dstSocket;    // 相手

    struct sockaddr_in srcAddr;
    struct sockaddr_in dstAddr;
    socklen_t dstAddrSize = sizeof( dstAddr );

    int  iRet;
    char pcBuf[256];

    // sockaddr_in 構造体のセット
    bzero( ( char* )&srcAddr, sizeof( srcAddr ) );
    srcAddr.sin_port        = htons( 9876 );
    srcAddr.sin_family      = AF_INET;
    srcAddr.sin_addr.s_addr = INADDR_ANY;

    // ソケットの生成(ストリーム型)
    srcSocket = socket( AF_INET, SOCK_STREAM, 0 );
    if ( srcSocket < 0 )
    {
        perror( "socket" );
        return( -1 );
    }

    // アドレス使用中エラーを回避する
    // これをしないと2回目のbindでエラーになる。
    // socketはclose後も2〜4分残る模様
    int on = 1;
    iRet = setsockopt( srcSocket
                     , SOL_SOCKET
                     , SO_REUSEADDR
                     , &on
                     , sizeof( on )
                     );
    if ( iRet < 0 )
    {
        perror( "setsockopt" );
        return( -2 );
    }

    // ソケットのバインド
    iRet = bind( srcSocket
               , ( struct sockaddr* )&srcAddr
               , sizeof( srcAddr )
               );
    if ( iRet < 0 )
    {
        perror( "bind" );
        return( -3 );
    }

    // 接続の許可
    iRet = listen( srcSocket, 1 );
    if ( iRet < 0 )
    {
        perror( "listen" );
        return( -4 );
    }

    // 接続の受付け
    outputLog( "SV""接続を待っています\n" );
    dstSocket = accept( srcSocket
                      , ( struct sockaddr* )&dstAddr
                      , &dstAddrSize
                      );
    outputLog( "SV""accept OK\n" );

    close( srcSocket );

    int iProc = 1;
    while( iProc )
    {
        int iInpt;
        outputLog( "SV""----------------------------------\n" );
        outputLog( "SV""(1) send messase\n" );
        outputLog( "SV""(9) end\n" );
        outputLog( "SV""input number: " );
        scanf( "%d", &iInpt );

        switch( iInpt )
        {
        case 1:
            // メッセージ送信
            memset( pcBuf, 0x00, sizeof( pcBuf ) );
            strcpy( pcBuf, "send server!!" );
            iRet = write( dstSocket, pcBuf, strlen( pcBuf ) );
            if ( iRet < 0 )
            {
                perror( "write" );
                return( -5 );
            }
            outputLog( "SV""send OK!!\n" );
            break;
        case 9:
            outputLog( "SV""終了します。\n" );
            iProc = 0;
            break;
        default:
            outputLog( "SV""番号を選んで下さい。\n" );
            break;
        }
    }

    close( dstSocket );

    outputLog( "SV""LC112Server END\n" );
    return( 0 );
}

本筋から離れますが、ログ出力の関数です。

outputLog.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: 
32: 
33: 
34: 
35: 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <time.h>

void outputLog( const char* kbn
              , const char* format, ...
              )
{
    char msg[256];
    va_list list;

    memset( msg, 0x00, sizeof( msg ) );

    va_start( list, format );
    vsprintf( msg, format, list );
    va_end( list );

    time_t timer;
    time_t timeRet;
    timeRet = time( &timer );
    struct tm* nowTM;
    nowTM = localtime( &timer );

    printf( "%02d:%02d:%02d %s %s"
          , nowTM->tm_hour
          , nowTM->tm_min
          , nowTM->tm_sec
          , kbn
          , msg
          );

    return;
}

ログ出力の関数の定義です。

outputLog.h
1: 
2: 
3: 
void outputLog ( const char* kbn
               , const char* format, ...
               );

メイクファイルです。

makefile
 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
# 2013/11/25 (c) ymlib.com
TARGET = LC112Server
OBJS = LC112Server.o outputLog.o
CC = /usr/bin/gcc

$(TARGET): $(OBJS)
$(CC) -o $@ $(OBJS)
.SUFFIXES: .c.o
.c.o:
$(CC) -Wall -c $< -g

clean:
rm -f $(TARGET) $(OBJS)

クライアント側のプログラムを作ったあと動作確認します。

>> 続き

▲ PageTop  ■ Home


Copyright (C) 2013 ymlib.com