Linux Cにおけるソケット通信(サーバ側:サンプルプログラム)
- 評価
- クリップ 0
- VIEW 3,345
◆行いたいこと
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ページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
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");
}
....
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.33%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
2018/06/29 13:31
ご教授ありがとうございます。ご指摘の方法にて上手くいきました。
ご指摘いただき「ハッ」としまし、まったく気づきませんでした。勉強になりました。