C에서 소켓 연결부를 완전히 파괴하는 방법
저는 소켓을 이용하여 리눅스에서 채팅 클라이언트를 만들었고, 연결을 완전히 파괴하고 싶습니다.다음은 코드의 관련 부분입니다.
int sock, connected, bytes_recieved , true = 1, pid;
char send_data [1024] , recv_data[1024];
struct sockaddr_in server_addr,client_addr;
int sin_size;
label:
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
perror("Socket");
exit(1);
}
if (setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&true,sizeof(int)) == -1)
{
perror("Setsockopt");
exit(1);
}
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(3128);
server_addr.sin_addr.s_addr = INADDR_ANY;
bzero(&(server_addr.sin_zero),8);
if (bind(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr))== -1)
{
perror("Unable to bind");
exit(1);
}
if (listen(sock, 5) == -1)
{
perror("Listen");
exit(1);
}
printf("\nTCPServer Waiting for client on port 3128");
fflush(stdout);
connected = accept(sock, (struct sockaddr *)&client_addr,&sin_size);
//necessary code
close(sock);
goto label;
그러나 'label'로 이동한 후 코드가 종료되고 오류 메시지가 표시되기 때문에 close(sock)가 연결 파괴를 완전히 닫지 않는 것으로 보입니다.
Unable to bind: Address already in use
그것은 연결이 다시 일어나지 않는다는 것입니다.무엇이 문제가 될 수 있습니까?미리 감사드립니다.
편집: 제가 실제로 원하는 것은 연결을 끊은 후 처음부터 스크립트를 실행할 때 새 프로그램으로 실행되어야 한다는 것입니다.어떻게 하면 되죠?
그close
call은 TCP 소켓이 닫혔음을 표시할 뿐입니다.공정상 더 이상 사용할 수 없습니다.그러나 커널은 일정 기간 동안 일부 리소스(TIME_WAIT, 2MLS 등)를 보유할 수 있습니다.
SO_REUSEADDR을 설정하면 바인딩 문제가 제거됩니다.
그래서 그 가치를 확인하세요.true
전화를 걸 때 0이 아닙니다.setsockopt
(overflow 버그가 덮어쓸 수 있음):
true = 1;
setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&true,sizeof(int))
있어pid
변수는 코드입니다.사용하는 경우fork
(접속 처리 프로세스를 시작하는 경우), 종료해야 합니다.sock
그것이 필요하지 않은 공정에서도.
처음에는 이름을 붙이기 때문에, 우리는 모두 같은 것들의 이름을 같게 짓습니다.
서버측:
소켓이 다음으로 넘어갔습니다.listen()
그다음에accept()
청취소켓을 부르도록 하겠습니다.소켓이 반환되었습니다.accept()
승인된 소켓을 호출합니다.
클라이언트 측:
소켓이 다음으로 넘어갔습니다.connect()
연결/연결 소켓을 호출합니다.
문제와 관련하여:
종료하려면accept()
ed connection은 선택적으로 먼저 사용한 후 다음을 사용하여 수락된 소켓(연결되었다고 부르는 것)을 닫습니다.
그런 다음 에 대한 호출 직전에 새 연결 루프를 수락하려면 다음과 같이 하십시오.accept()
, 경유하지 않음bind()
그리고.listen()
다시.
오직.
종료 및 보류 중인 것을 제거하려면 청취 소켓을 닫습니다. connect()
뒤에 발행된accept()
반환된
연결된 소켓을 닫는 것을 잊었기 때문에 연결이 여전히 활성화되어 있습니다.청취 소켓을 닫는다고 해서 연결된 소켓이 자동으로 닫히지는 않습니다.
//necessary code
close(connected); // <---- add this line
close(sock);
goto label;
나는 당신이 왜 EADDRIN을 사용하는지 잘 모르겠습니다.그 코드는 리눅스와 macos 둘 다에서 잘 작동했습니다.
은 입니다.SO_REUSEADDR
.
만약 당신이 청취자이고, 연결을 수락한다면, 당신은 전화를 해야 합니다.shutdown()
전에close()
(적어도 리눅스에서는).그냥 전화하면.close()
, 당신은 접속을 닫기 위해 클라이언트가 보내고 있는 FIN을 ACK하지 않을 것이고, 클라이언트는 a에 갇힐 수 있습니다.CLOSE_WAIT
주.
왜냐하면 연결은 상대방이 인정할 때나 일정 시간이 지난 후에 실제로 닫히기 때문입니다.이건 정상적인 행동입니다...
편집: 코드를 실제로 확인하지는 않았지만 다른 사용자의 댓글을 보면 잘못된 행동을 하고 있습니다.
언급URL : https://stackoverflow.com/questions/10619952/how-to-completely-destroy-a-socket-connection-in-c
'programing' 카테고리의 다른 글
Jest에서의 XMLHttpRequest 테스트 (0) | 2023.10.24 |
---|---|
데이터 변환 방법javascript로 파일 개체에 URL을 지정하시겠습니까? (0) | 2023.10.24 |
XPath: 텍스트 노드 선택 (0) | 2023.10.24 |
mysql 등가 데이터 유형 (0) | 2023.10.24 |
매크로가 정의되어 있고 동시에 특정 값과 동일한지 확인할 수 있는 방법이 있습니까? (0) | 2023.10.19 |