[解決済み] Operation not supported エラーが発生するのですが
2022-02-11 23:13:50
質問
私はUbuntuを仮想ボックス上で使用しており、サーバーとクライアントを使用した仮想ハングマンゲームを持っています。複数のクライアントが一度にサーバーに接続できますが、ゲームが終了すると、サーバー上で "接続を受け入れる:操作はサポートされていません" というエラーが表示されます。
以下は私のコードです。
#include <sys/types.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <syslog.h>
#include <signal.h>
#include <errno.h>
#include <string.h>
extern time_t time ();
int maxlives = 12;
char *word [] = {
# include "words"
};
# define NUM_OF_WORDS (sizeof (word) / sizeof (word [0]))
# define MAXLEN 80 /* Maximum size in the world of Any string */
# define HANGMAN_TCP_PORT 1066
int main ()
{
int sock, fd, client_len;
pid_t pid;
struct sockaddr_in server, client;
srand ((int) time ((long *) 0)); /* randomize the seed */
sock = socket (AF_INET, SOCK_STREAM, 0);//0 or IPPROTO_TCP
if (sock <0) { //This error checking is the code Stevens wraps in his Socket Function etc
perror ("creating stream socket");
exit (1);
}
server.sin_family = AF_INET;
server.sin_addr.s_addr = htonl(INADDR_ANY);
server.sin_port = htons(HANGMAN_TCP_PORT);
if (bind(sock, (struct sockaddr *) & server, sizeof(server)) <0) {
perror ("binding socket");
exit (2);
}
listen (sock, 5);
while (1) {
client_len = sizeof (client);
if ((fd = accept (sock, (struct sockaddr *) &client, &client_len)) <0)
{
perror ("accepting connection");
exit (3);
}
else
{
//make a child using fork();
// fork();
pid = fork();
//if id == 0, it is child
if(pid ==0)
{
//close the listening port, play hangman
close(sock);
play_hangman (fd, fd);
close(fd);
}
//else, it is parent, ignore child and guest, listen for more guests to make more children with
else {
close (fd);
}
}
}
close(fd);
}
/* ---------------- Play_hangman () ---------------------*/
play_hangman (int in, int out)
{
char * whole_word, part_word [MAXLEN],
guess[MAXLEN], outbuf [MAXLEN];
int lives = maxlives;
int game_state = 'I';//I = Incomplete
int i, good_guess, word_length;
char hostname[MAXLEN];
gethostname (hostname, MAXLEN);
sprintf(outbuf, "Playing hangman on host% s: \n \n", hostname);
write(out, outbuf, strlen (outbuf));
/* Pick a word at random from the list */
whole_word = word[rand() % NUM_OF_WORDS];
word_length = strlen(whole_word);
syslog (LOG_USER | LOG_INFO, "server chose hangman word %s", whole_word);
/* No letters are guessed Initially */
for (i = 0; i <word_length; i++)
part_word[i]='-';
part_word[i] = '\0';
sprintf (outbuf, "%s %d \n", part_word, lives);
write (out, outbuf, strlen(outbuf));
while (game_state == 'I')
/* Get a letter from player guess */
{
while (read (in, guess, MAXLEN) <0) {
if (errno != EINTR)
exit (4);
printf ("re-read the startin \n");
} /* Re-start read () if interrupted by signal */
good_guess = 0;
for (i = 0; i <word_length; i++) {
if (guess [0] == whole_word [i]) {
good_guess = 1;
part_word [i] = whole_word [i];
}
}
if (! good_guess) lives--;
if (strcmp (whole_word, part_word) == 0)
game_state = 'W'; /* W ==> User Won */
else if (lives == 0) {
game_state = 'L'; /* L ==> User Lost */
strcpy (part_word, whole_word); /* User Show the word */
}
sprintf (outbuf, "%s %d \n", part_word, lives);
write (out, outbuf, strlen (outbuf));
}
}
問題はここにあるようです。
//こちら
while (1) {
client_len = sizeof (client);
if ((fd = accept (sock, (struct sockaddr *) &client, &client_len)) <0)
{
perror ("accepting connection");
exit (3);
}
else
{
//make a child using fork();
// fork();
pid = fork();
//こちらへ
しかし、何が間違っているのか、このエラーを修正する方法がわかりません。
解決方法を教えてください。
ゲームが終了したら、子プロセスを終了させる必要があります。しかし、その代わりに
accept()
ループは、すでに閉じた
sock
ディスクリプタを使用します。
if(pid == 0)
{
//close the listening port, play hangman
close(sock);
play_hangman (fd, fd);
// child has done its job, terminate immediately
_Exit(0);
}
//else, it is parent, ignore child and guest, listen for more guests to make more children with
else {
close (fd);
}
おそらく、子プロセスが実行されているとき
play_hangman()
に格納されている値です。
sock
は、以前にそのディスクリプタを閉じているので、別のファイルに再利用されるかもしれません。そして、その新しいファイルは間違いなくリスニング用ソケットではありません。その結果
accept()
で失敗します。
Operation not supported
.
関連
-
[解決済み] (.text+0x20): `main'への未定義の参照と関数への未定義の参照
-
[解決済み】エラー:'for'ループの初期宣言はC99モードでしかできない【重複
-
[解決済み】 strcpyとstrdupの比較
-
[解決済み】「無効なイニシャライザー」と表示されるのですが、何が間違っているのでしょうか?
-
[解決済み】 switch case: error: case label does not reduce to an integer constant
-
[解決済み] struct has no member named
-
[解決済み】C 未知の型名「my_structure」。
-
[解決済み】C言語でint64_t型を表示する方法
-
[解決済み】LinuxのI_PUSHに相当するもの
-
[解決済み] なぜsizeof(x++)はxをインクリメントしないのですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】Cコンパイルエラーです。Idは1終了ステータスを返した
-
[解決済み】 `S_ISREG()` とは何ですか、そして何をするのですか?
-
[解決済み】ISO C90では、C言語での宣言とコードの混在が禁止されています。
-
[解決済み] テスト
-
[解決済み】エラー。非スカラー型への変換を要求された
-
[解決済み】警告:組み込み関数'printf'の非互換な暗黙の宣言(デフォルトで有効]
-
[解決済み】コンパイラの警告 - 真理値として使用される代入の周囲に括弧を付けることを推奨する
-
[解決済み】0LLや0x0ULの意味は何ですか?
-
[解決済み】警告:式の結果が未使用の場合
-
[解決済み】Linuxソケットのwrite()でBad File Descriptorが発生するC