Linux 네트워크 프로 그래 밍 의 connect 함수 분석
socket -> connect -> recv/send -> close
그 중에서 socket 은 의심 할 만 한 것 이 없습니다. 주로 서버 와 데 이 터 를 교환 하 는 소켓 을 만 들 고 빠르게 돌아 갑 니 다. 이때 데 이 터 는 네트워크 카드 를 통 해 보 내지 않 고 그 다음 에 connect 함 수 는 네트워크 데 이 터 를 보 냅 니 다. TCP 의 세 번 의 악수 도 바로 이때 부터 connect 는 먼저 SYN 가방 을 서버 에 보 냅 니 다.그리고 최초의 CLOSED 상태 에서 SYNSENT 상태, 이 상태 에서 서버 의 확인 패 키 지 를 기다 리 고 있 습 니 다. 보통 이 확인 패 키 지 는 곧 도착 하기 때문에 netstat 명령 으로 SYN 을 볼 수 없습니다.SENT 상태의 존 재 는 극단 적 인 상황 에 대한 시 뮬 레이 션 을 통 해 클 라 이언 트 로 하여 금 임의로 지정 한 서버 (예 를 들 어 IP 주 소 는 88.8.8 8.8) 에 연결 하 게 할 수 있 습 니 다. 이 서버 는 SYN 가방 의 확인 가방 (SYN ACK) 에 피드백 하지 않 기 때문에 클 라 이언 트 는 일정한 시간 안에 SYN 에 있 을 것 입 니 다.SENT 상태 이 며, 예 정 된 시간 초과 (예 를 들 어 3 분) 이후 connect 함수 에서 되 돌 아 옵 니 다. connect 호출 이 실패 하면 (ESTABLISHED 상태 에 도달 하지 못 함) 이 소켓 을 사용 할 수 없습니다. connect 함 수 를 다시 호출 하려 면 socket 함 수 를 다시 사용 하여 새 소켓 을 만들어 야 합 니 다.
다음은 실례 분석 을 결합 하여 클 라 이언 트 코드 는 다음 과 같다.
/**
* client.c
*
* TCP client program, it is a simple example only.
* Writen By: Zhou Jianchun
* Date: 2011.08.11
*
* Compiled With: gcc -o client client.c
* Tested On: Ubuntu 11.04 LTS
* gcc version: 4.5.2
*
*/
#include <stdio.h>
#include <sys/socket.h>
#include <unistd.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#define SERVER_PORT 20000
void usage(char *name)
{
printf("usage: %s IP
", name);
}
int main(int argc, char **argv)
{
int server_fd, client_fd, length = 0;
struct sockaddr_in server_addr, client_addr;
socklen_t socklen = sizeof(server_addr);
if(argc < 2)
{
usage(argv[0]);
exit(1);
}
if((client_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("create socket error, exit!
");
exit(1);
}
srand(time(NULL));
bzero(&client_addr, sizeof(client_addr));
client_addr.sin_family = AF_INET;
client_addr.sin_addr.s_addr = htons(INADDR_ANY);
bzero(&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
inet_aton(argv[1], &server_addr.sin_addr);
server_addr.sin_port = htons(SERVER_PORT);
if(connect(client_fd, (struct sockaddr*)&server_addr, socklen) < 0)
{
printf("can not connect to %s, exit!
", argv[1]);
printf("%s
", strerror(errno));
exit(1);
}
return 0;
}
컴 파일 완료 후 실행:
zhou@neptune:~/data/source$ ./client 88.88.88.88
이 때 프로그램 은 connect 함수 에서 대기 시간 을 막 고 약 180 초 후에 출력 합 니 다.
can not connect to 88.88.88.88, exit!
Connection timed out
현재 connect 의 반환 값 은 ETIMEOut 입 니 다.
이 과정 에서 우 리 는 netstat 명령 으로 연결 상 태 를 조회 할 수 있 습 니 다.
zhou@neptune:~/data/source$ sudo netstat -natp |grep 20000
tcp 0 1 192.168.0.4:44203 88.88.88.88:20000 SYN_SENT 5954/client
이때 TCP 연결 상 태 를 SYN 으로 볼 수 있 습 니 다.SENT 는 SYN 가방 을 발송 한 후 서버 로부터 SYN ACK 가방 을 돌려 받 지 못 했다 는 뜻 이다.
그 다음 에 우 리 는 이 클 라 이언 트 프로그램 을 사용 하여 자신의 기 계 를 연결 합 니 다. 테스트 할 때 나의 IP 주 소 는 192.168.0.4 이 고 무선 랜 입 니 다. 결 과 는 다음 과 같 습 니 다.
zhou@neptune:~/data/source$ ./client 192.168.0.4
can not connect to 192.168.0.4, exit!
Connection refused
내 기기 에 지정 한 포트 (20000) 에서 감청 하 는 서버 프로그램 이 실행 되 지 않 았 기 때문에 이 연결 은 프로 토 콜 스 택 에서 직접 거부 되 었 습 니 다 (RST 형식의 TCP 패 키 지 를 보 내 는 것 을 통 해). connect 는 즉시 되 돌아 오고 값 은 ECONNREFUSED 입 니 다.
같은 랜 에 존재 하지 않 는 호스트 를 연결 할 때의 상황 을 살 펴 보 자. 예 를 들 어 이 상상 하 는 호스트 의 IP 주 소 는 192.168.0.188 이다.
zhou@neptune:~/data/source$ ./client 192.168.0.188
can not connect to 192.168.0.188, exit!
No route to host
로 컬 랜 에 있 는 이 호스트 가 존재 하지 않 기 때문에 ARP 요청 이 응답 하지 않 습 니 다. 게 이 트 웨 이 는 호스트 가 접근 할 수 없 는 ICMP 메시지 에 응답 하고 connect 는 EHostUNREACH 로 돌아 갑 니 다.
이로써 connect 함수 에 대한 분석 은 끝 났 습 니 다. 본인 의 수준 이 제한 되 어 있 기 때문에 블 로그 의 부적 절하 거나 잘못된 점 이 불가피 합 니 다. 독자 의 비판 과 지적 을 간절히 바 랍 니 다. 또한 독자 가 관련 내용 을 공동으로 토론 하 는 것 도 환영 합 니 다. 기꺼이 교류 하고 싶다 면 귀중 한 의견 을 남 겨 주 십시오. 감사합니다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Linux Shell 프로 그래 밍 - 텍스트 처리 grep, sed사용자 가 지정 한 '모드' 에 따라 대상 텍스트 를 일치 하 게 검사 하고 일치 하 는 줄 을 인쇄 합 니 다. ##포함 되 지 않 음, 역방향 일치 \ ##키워드 앞 뒤 가 맞지 않 고 키워드 만 일치 합 니 다...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.