質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.51%

  • Linux

    3778questions

    Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

  • C

    3687questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

  • TCP

    163questions

    TCP(Transmission Control Protocol)とは、トランスポート層のプロトコルで、コネクション型のデータサービスです。

  • Debian

    119questions

    Debianは、Debian GNU/Linux などのOS(オペレーティングシステム)です。

Linux Cにおけるソケット通信(サーバ側:サンプルプログラム)

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 325

cafe_takai

score 17

◆行いたいこと
Linux(debian8)・Cにおけるサーバ側ソケットサンプルプログラムを動かしたい。

◆症状
サーバ側プログラムにおいて、UDPでの通信は上手く行くが、TCPの通信において、次のエラーが出てしまいます。
failed to receive initial bytes from clienterrno is : Socket operation on non-socket

◆調べたこと
プログラム中のclientHandleがゼロであり、これに起因しているであることは分かったのですが、関連するコマンドを調べたのですが、なぜ取得できないのかが分かりません。

どなた様か、ご教授いただけましたら幸いです。

#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>

#define MAX_BUF 256

void post_error(const char* inMsg){
    fprintf(stderr, "%s", inMsg);
    perror("errno is ");
    exit(-1);
}

void handle_client(int client){
    char buffer[MAX_BUF];
    int received = -1;

    /* [TCP]メッセージを受ける */
    received = recv(client, buffer, MAX_BUF, 0);
    if (received < 0) post_error("error: connection - failed to receive initial bytes from client");

    while (received > 0){
        printf("%s", buffer);
        received = recv(client, buffer, MAX_BUF, 0);

        if (received < 0)
            post_error("error: connection - failed to received pending bytes from client");
    }
    close(client);
}

// メインプログラム...
int main(int argc, char* argv[]){
    int serverHandle;
    int clientHandle;
    struct sockaddr_in server;
    struct sockaddr_in client;

    if (argc != 3) post_error("usage: server [tcp or udp] [port number]");

    int udp;
    if (strcmp(argv[1], "tcp") == 0){
        udp = 0;
        serverHandle = socket(AF_INET, SOCK_STREAM, 0);
    }
    else if (strcmp(argv[1], "udp") == 0){
        udp = 1;
        serverHandle = socket(AF_INET, SOCK_DGRAM, 0);
    } else {
         post_error("error: invalid arguments - first argument must be either \"tcp\" or \"udp\"");
    }

    /* 構造体のセット... */
    memset(&server, 0, sizeof(server));
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = htonl(INADDR_ANY);
    server.sin_port = htons(atoi(argv[2]));

    /* バインド */
    if (bind(serverHandle, (struct sockaddr*)&server, sizeof(server)) < 0)
        post_error("error: failed to bind to target port");

    if (!udp)
    {
        /* [TCP] 許可待ち */
        if (listen(serverHandle, 1) < 0)
            post_error("error: failed to listen on bound port");
    }

    fprintf(stdout, "server initialized.\nwaiting for messages...\n");
    fflush(stdout);

    /* データが来るのを待つ */
    while (1){
        if (udp) {
            char buffer[MAX_BUF];
            socklen_t len = sizeof(client);
            ssize_t received = recvfrom(serverHandle, buffer, MAX_BUF, 0, (struct sockaddr*)&client, &len);

            fprintf(stdout, "> %s", buffer);
            fflush(stdout);
        }
        else {
            /* 接続待ち */
          socklen_t len = sizeof(client);
            if (clientHandle = accept(serverHandle, (struct sockaddr *) &client, &len) < 0)
                post_error("error: failed to accept client connection");

            fprintf(stdout, "client connected: %s\n", inet_ntoa(client.sin_addr));
            fflush(stdout);
            handle_client(clientHandle);
        }
    }
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+2

ご提示のコードに問題があって、acceptで返されたクライアントのソケットディスクリプターがなくなってしまっています。以下の部分で、

            /* 接続待ち */
          socklen_t len = sizeof(client);
            if (clientHandle = accept(serverHandle, (struct sockaddr *) &client, &len) < 0)

演算子の優先順位で、=より<の方が優先順位が高い為にaccept() < 0が最初に評価されて、偽、つまり0 になり、clientHandle に=0が代入されています。

下のように直せば、意図通り正しく動作します。

clientHandle = accept(serverHandle, (struct sockaddr *) &client, &len);
if (clientHandle < 0) {
    post_error("error: failed to accept client connection");
}
....

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/06/29 13:31

    dodox86 様
    ご教授ありがとうございます。ご指摘の方法にて上手くいきました。
    ご指摘いただき「ハッ」としまし、まったく気づきませんでした。勉強になりました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.51%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • Linux

    3778questions

    Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

  • C

    3687questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

  • TCP

    163questions

    TCP(Transmission Control Protocol)とは、トランスポート層のプロトコルで、コネクション型のデータサービスです。

  • Debian

    119questions

    Debianは、Debian GNU/Linux などのOS(オペレーティングシステム)です。