지금부터 구현할 서버와 클라이언트의 동작방식은 다음과 같습니다.
- 클라이언트는 서버에 접속하자마자 피연산자의 개수 정보를 1바이트 정수형태로 전달
- 피연산자의 개수만큼 4바이트의 정수를 전달
- 정수를 전달한 다음, 1바이트 크기의 연산자의 종류 전달 (+,-,*)
- 서버의 연산 결과를 4바이트 정수로 받아옴
- 연산 결과를 얻은 클라이언트는 서버와 연결 종료
클라이언트입니다. socket 생성, connect 호출까지는 똑같습니다.
선언되어 있는 변수와 매크로는 다음과 같습니다.
#define BUF_SIZE 1024
#define RLT_SIZE 4
#define OPSZ 4
// 버퍼 크기, 결과 크기, 피연산자 크기
int sock;
char opmsg[BUF_SIZE] // 서버에 보낼 문자열
int result, cnt, i; //결과 담을 변수, 연산할 정수 개수, 반복문에 사용
struct sockaddr_in serv_adr;
scanf("%d", &cnt);
opmsg[0]=(char)cnt;
먼저 1바이트 크기의 피연산자 개수 정보를 문자열의 맨 앞에 저장해줍니다. int형으로 입력받은 다음, char형으로 형변환을 해 1바이트 크기로 줄여줬습니다.
for(i=0; i<cnt; i++){
scanf("%d",(int*)
&opmsg[i*OPSZ+1]);
}
다음으로 피연산자를 입력받습니다. 피연산자는 4바이트로 받지만 입력은 1바이트 char형 배열에 받으므로, 피연산자가 배열을 4칸씩 사용할 수 있도록 4칸 단위로 뛰어서 입력받아줍니다.
fgetc(stdin);
scanf("%c",&opmsg[cnt*OPSZ+1]);
write(sock, opmsg, cnt*OPSZ+2);
read(sock, &result, RLT_SIZE);
마지막 입력으로 연산자의 종류를 받아줍니다. 그 이전에, fgetc(stdin)을 해줬는데 그 앞 입력에서 입력버퍼에 가비지가 생겨 비워지지 않아 연산자 입력이 정상적으로 안됩니다. 따라서 fgetc를 통해 입력버퍼를 비워줬습니다.
그 후 서버에 문자열을 넘겨주고, 결과를 받아옵니다.
이제 서버입니다. 소켓을 생성하고 bind, listen 호출까지 같습니다.
사용된 변수는 다음과 같습니다.
#define BUF_SIZE 1024
#define OPSZ 4
int sock, clnt_sock;
struct sockaddr_in serv_adr, clnt_adr;
int oparr[BUF_SIZE]; // 피연산자 담을 정수 배열
int i, j, cnt, result;
char operator;
clnt_sock=accept(sock,(struct sockaddr*)&clnt_adr, &clnt_adr_sz);
...
read(clnt_sock,&cnt,1);
먼저 소켓을 생성하고, 피연산자 개수 정보를 클라이언트로부터 받아옵니다.
for(j=0; j<cnt; j++){
read(clnt_sock,&oparr[j],OPSZ);
}
피연산자를 담을 정수 배열에 피연산자를 담아줍니다. 앞서 클라이언트에서 4바이트씩 저장해뒀으므로, 4바이트씩 읽어주면 됩니다.
read(clnt_sock,&operator,1);
result=calculate(cnt,oparr,operator);
write(clnt_sock,(char*)&result,sizeof(result));
close(clnt_sock);
마지막으로 연산자를 읽어주고, 결과를 구해줍니다. (calculate 함수는 결과를 구해주는 간단한 함수라 생략)
클라이언트에 결과를 넘겨주고 연결을 종료합니다.
다음은 각각 클라이언트와 서버의 전체 소스코드입니다.
https://github.com/kjmin622/TCP-IP-Socket-Programing/blob/master/src/op_client.c
https://github.com/kjmin622/TCP-IP-Socket-Programing/blob/master/src/op_server.c
'현생 > TCP 소켓 프로그래밍' 카테고리의 다른 글
5-3 TCP의 내부 동작 원리 (TCP 흐름 제어) [TCP/IP] (0) | 2022.01.17 |
---|---|
5-2 TCP 소켓의 입출력 버퍼 [TCP/IP] (0) | 2022.01.17 |
4-2. echo 서버와 클라이언트 구현 [TCP/IP][C][LINUX] (0) | 2022.01.15 |
4-1. TCP/IP 프로토콜 스택 [TCP/IP][C][LINUX] (0) | 2022.01.15 |
extra. POSIX에서 정의한 자료형 [TCP/IP][C] (0) | 2022.01.14 |