#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#define PORT 10000
int main(int argc, char const *argv[]) {
int sock = 0, valread;
struct sockaddr_in serv_addr;
char *hello = (char*)"Hello from client";
char buffer[1024] = {0};
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
printf("\n Socket creation error \n");
}
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
if (inet_pton(AF_INET, "218.48.17.230", &serv_addr.sin_addr) <= 0) {
printf("\n Invalid address/ Address not supported \n");
return -1;
}
if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
printf("\nConnection Failed \n");
return -1;
}
send(sock, hello, strlen(hello), 0);
printf("Hello message sent\n");
valread = read(sock, buffer, 1024);
printf("%s\n", buffer);
return 0;
}
linux 기반 클라이언트 사이드 코드이다.
socket, connect, send/recv, inet_pton으로 구성되어있다.
windows 기반 클라이언트 사이드는 원리는 똑같으나 꽤 상이한 코드를 사용한다.
소켓 생성은 server쪽이랑 동일하다.
inet_pton()함수는 사람이 알아보기 쉬운 텍스트 형태의 IPv4, IPv6 주소를 binary로 변환한다.
#include <arpa/inet.h> 헤더파일에 포함되어 있다.
원형은 다음과 같다.
int inet_pton(int af, const char *src, void *dst);
af = address family를 지정한다. IPv4 인지, IPv6인지 전달한다.
src = 문자열 형태의 ip주소를 받는다.
dst = src의 문자열주소를 binary로 변환하고 복사하는 메모리의 포인터이다.
if (inet_pton(AF_INET, "218.48.17.230", &serv_addr.sin_addr) <= 0) {
printf("\n Invalid address/ Address not supported \n");
return -1;
}
실제로 적용하면 다음과 같다.
보이는것처럼 ip를 받아서 이를 sockaddr_in struct의 sin_addr로 넣는것이다.
int connect(int sockfd, struct sockaddr *serv_addr, int addrlen)
server에 연결을 담당하는 함수이다.
구조를 보면 매우 단순하다. 연결한 소켓의 파일 디스크립터, sockaddr 구조체, 그리고 주소의 길이이다.
if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
printf("\nConnection Failed \n");
return -1;
}
실제로 사용하면 다음과 같이 쓴다.
위에서 inet pton을 통해 binary로 바꿔준 주소가 struct sockaddr 안에 있게 된다. 그 주소를 기반으로 connect하는 함수이다.
이 과정은 server side랑 다를게 없다.
일단 linux 기반에서의 서버, 클라이언트 사이드의 코드를 모두 알아보았고, 이를 실행하려면
리눅스 기반 서버컴퓨터에서 서버를 실행 / 윈도우에서 ssh로 클라이언트를 실행
리눅스 기반 서버컴퓨터에서 서버를 실행 / 터미널을 하나 더 켜서 실행
다만 실제로 클라이언트들이 리눅스를 쓰는 일은 거의 없을것이다. 따라서 윈도우 기반 클라이언트 코트 역시 분석해보도록 하자