私はCとLinuxに初めてアクセスし、Ubuntuシステムでコンパイルして実行したCコードを使用してデータを交換するためにTCPソケットサーバーを設定しようとしています。
チュートリアルでサーバーを起動し、クライアントコードを使用してデータ(時刻と日付)を受信する次のコード(以下を参照)をコピーしました(テスト目的で同じシステム上)。
その後、Ubuntuシステムを再起動しましたが、それ以降サーバーを起動できなくなりました。
その後、次のコードに例外処理を追加しましたが、「バインドできません」エラー番号22が発生します。これは「無効な引数」を意味しますか?以前は同じコードがうまく機能していたので、これは私には理解できません。
私は「古い」ソケットがタイムスタンバイ状態にあるかまだ閉じていないと仮定していますが、「ss -all state xxx」を使用して他のすべての状態のすべての接続を調べましたが、すべてが問題ないようです。
また、別のポートとコードを試してみましたが、同じ問題が発生しました。
他に何を試すべきかわからないので、誰でも私を助けることができることを願っています。
// C-Code Server
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <time.h>
int main(int argc, char *argv[])
{
int listenfd = 0, connfd = 0;
struct sockaddr_in serv_addr;
char sendBuff[1025];
time_t ticks;
//Open a socket
listenfd = socket(AF_INET, SOCK_STREAM, 0);
memset(&serv_addr, '0', sizeof(serv_addr));
memset(sendBuff, '0', sizeof(sendBuff));
if (listenfd == -1) {
printf("Error: unable to open a socket\n");
exit(1);
}
//Create an Adress
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htons(INADDR_ANY);
serv_addr.sin_port = htons(1234);
//Macht schon benutzte Adresse mit SO_REUSEADDR nutzbar
int opt = 1;
if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt))<0) {
perror("setsockopt");exit(EXIT_FAILURE);
}
if(setsockopt(listenfd, SOL_SOCKET, SO_REUSEPORT, (char *)&opt, sizeof(opt))<0) {
perror("setsockopt");exit(EXIT_FAILURE);
}
bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
if ((bind(listenfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr))) == -1) {
printf("Error: unable to bind\n");
printf("Error code: %d\n", errno);
exit(1);
}
listen(listenfd, 10);
while(1)
{
connfd = accept(listenfd, (struct sockaddr*)NULL, NULL);
if (connfd == -1) {
printf("Error: unable to accept connections\n");
printf("Error code: %d\n", errno);
exit(1);
}
ticks = time(NULL);
snprintf(sendBuff, sizeof(sendBuff), "%.24s\r\n", ctime(&ticks));
write(connfd, sendBuff, strlen(sendBuff));
close(connfd);
sleep(1);
}
}
答え1
バインディング(2)言う:
EINVAL The socket is already bound to an address.
実際、同じソケットでバインディング()を2回呼び出しています。
bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)); if ((bind(listenfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr))) == -1) { printf("Error: unable to bind\n"); printf("Error code: %d\n", errno); exit(1); }
最初のバインディング()が削除されたら、接続時に日付を受け取ることができます。