저는 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.
실제로 동일한 소켓에서 바인딩()을 두 번 호출하고 있습니다.
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); }
첫 번째 바인딩()이 제거되면 연결 시 날짜를 받을 수 있습니다.