소켓 프로그래밍이란 무엇입니까?
소켓 프로그래밍은 네트워크의 두 노드를 연결하여 서로 통신하는 방법입니다. 한 소켓(노드)은 IP의 특정 포트를 수신하는 반면 다른 소켓은 다른 소켓에 연결하여 연결을 형성합니다. 클라이언트가 서버에 접근하는 동안 서버는 리스너 소켓을 형성합니다.
서버 및 클라이언트 모델의 상태 다이어그램

소켓의 서버 및 클라이언트 모델에 대한 상태 다이어그램
서버 단계
서버는 다음 단계를 통해 생성됩니다.
테스트 유형
1. 소켓 생성
int sockfd = socket(domain, type, protocol)>
- sockfd: 소켓 설명자, 정수(파일 핸들과 같은) domain: 정수, 통신 도메인을 지정합니다. 동일한 호스트의 프로세스 간 통신을 위해 POSIX 표준에 정의된 AF_LOCAL을 사용합니다. IPV4로 연결된 서로 다른 호스트의 프로세스 간 통신을 위해 IPV6으로 연결된 프로세스에 AF_INET 및 AF_I NET 6을 사용합니다. 유형: 통신 유형
SOCK_STREAM: TCP(신뢰성, 연결 지향)
SOCK_DGRAM: UDP(신뢰할 수 없음, 연결 없음) 프로토콜: 인터넷 프로토콜(IP)에 대한 프로토콜 값으로 0입니다. 이는 패킷의 IP 헤더에 있는 프로토콜 필드에 나타나는 숫자와 동일합니다.(자세한 내용은 man 프로토콜 참조)
2. 세트톡옵트
이는 파일 설명자 sockfd가 참조하는 소켓에 대한 옵션을 조작하는 데 도움이 됩니다. 이는 완전히 선택 사항이지만 주소와 포트를 재사용하는 데 도움이 됩니다. 이미 사용 중인 주소와 같은 오류를 방지합니다.
int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);>
3. 바인딩
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);>
소켓이 생성된 후 바인딩 함수는 소켓을 addr(사용자 정의 데이터 구조)에 지정된 주소와 포트 번호에 바인딩합니다. 예제 코드에서는 서버를 로컬 호스트에 바인딩하므로 INADDR_ANY를 사용하여 IP 주소를 지정합니다.
4. 들어보세요
int listen(int sockfd, int backlog);>
서버 소켓을 수동 모드로 전환하여 클라이언트가 연결을 위해 서버에 접근할 때까지 기다립니다. 백로그는 sockfd에 대해 보류 중인 연결 대기열이 커질 수 있는 최대 길이를 정의합니다. 대기열이 가득 찼을 때 연결 요청이 도착하면 클라이언트는 ECONNREFUSED 표시와 함께 오류를 수신할 수 있습니다.
5. 수락
int new_socket= accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);>
이는 청취 소켓인 sockfd에 대해 보류 중인 연결 대기열에서 첫 번째 연결 요청을 추출하고, 새로 연결된 소켓을 생성하고, 해당 소켓을 참조하는 새 파일 설명자를 반환합니다. 이 시점에서 클라이언트와 서버 사이에 연결이 설정되고 데이터를 전송할 준비가 됩니다.
클라이언트를 위한 단계
1. 소켓 연결: 서버의 소켓 생성과 정확히 동일
2. 연결: connect() 시스템 호출은 파일 설명자 sockfd가 참조하는 소켓을 addr이 지정한 주소에 연결합니다. 서버의 주소와 포트는 addr에 지정됩니다.
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);>
구현
여기서는 클라이언트/서버 모델을 보여주기 위해 서버와 클라이언트 간에 하나의 hello 메시지를 교환합니다.
서버를 생성하는 C 프로그램
서버.c
씨
// Server side C program to demonstrate Socket> // programming> #include> #include> #include> #include> #include> #include> #define PORT 8080> int> main(>int> argc,>char> const>* argv[])> {> >int> server_fd, new_socket;> >ssize_t valread;> >struct> sockaddr_in address;> >int> opt = 1;> >socklen_t addrlen =>sizeof>(address);> >char> buffer[1024] = { 0 };> >char>* hello =>'Hello from server'>;> >// Creating socket file descriptor> >if> ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) <0) {> >perror>(>'socket failed'>);> >exit>(EXIT_FAILURE);> >}> >// Forcefully attaching socket to the port 8080> >if> (setsockopt(server_fd, SOL_SOCKET,> >SO_REUSEADDR | SO_REUSEPORT, &opt,> >sizeof>(opt))) {> >perror>(>'setsockopt'>);> >exit>(EXIT_FAILURE);> >}> >address.sin_family = AF_INET;> >address.sin_addr.s_addr = INADDR_ANY;> >address.sin_port = htons(PORT);> >// Forcefully attaching socket to the port 8080> >if> (bind(server_fd, (>struct> sockaddr*)&address,> >sizeof>(address))> ><0) {> >perror>(>'bind failed'>);> >exit>(EXIT_FAILURE);> >}> >if> (listen(server_fd, 3) <0) {> >perror>(>'listen'>);> >exit>(EXIT_FAILURE);> >}> >if> ((new_socket> >= accept(server_fd, (>struct> sockaddr*)&address,> >&addrlen))> ><0) {> >perror>(>'accept'>);> >exit>(EXIT_FAILURE);> >}> >valread = read(new_socket, buffer,> >1024 - 1);>// subtract 1 for the null> >// terminator at the end> >printf>(>'%s
'>, buffer);> >send(new_socket, hello,>strlen>(hello), 0);> >printf>(>'Hello message sent
'>);> >// closing the connected socket> >close(new_socket);> >// closing the listening socket> >close(server_fd);> >return> 0;> }> |
>
이진 트리 대 bst
>
클라이언트를 생성하는 C 프로그램
클라이언트.c
씨
// Client side C program to demonstrate Socket> // programming> #include> #include> #include> #include> #include> #define PORT 8080> int> main(>int> argc,>char> const>* argv[])> {> >int> status, valread, client_fd;> >struct> sockaddr_in serv_addr;> >char>* hello =>'Hello from client'>;> >char> buffer[1024] = { 0 };> >if> ((client_fd = socket(AF_INET, SOCK_STREAM, 0)) <0) {> >printf>(>'
Socket creation error
'>);> >return> -1;> >}> >serv_addr.sin_family = AF_INET;> >serv_addr.sin_port = htons(PORT);> >// Convert IPv4 and IPv6 addresses from text to binary> >// form> >if> (inet_pton(AF_INET,>'127.0.0.1'>, &serv_addr.sin_addr)> ><= 0) {> >printf>(> >'
Invalid address/ Address not supported
'>);> >return> -1;> >}> >if> ((status> >= connect(client_fd, (>struct> sockaddr*)&serv_addr,> >sizeof>(serv_addr)))> ><0) {> >printf>(>'
Connection Failed
'>);> >return> -1;> >}> >send(client_fd, hello,>strlen>(hello), 0);> >printf>(>'Hello message sent
'>);> >valread = read(client_fd, buffer,> >1024 - 1);>// subtract 1 for the null> >// terminator at the end> >printf>(>'%s
'>, buffer);> >// closing the connected socket> >close(client_fd);> >return> 0;> }> |
>
>
산출
우분투 빌드 필수
Client:Hello message sent Hello from server Server:Hello from client Hello message sent>
컴파일 중
gcc client.c -o client gcc server.c -o server>
다음: C/C++의 소켓 프로그래밍: 멀티 스레딩 없이 서버에서 여러 클라이언트 처리