간단한 소켓 통신
리눅스에서 HOME폴더에
마우스 우 클릭해서 새 도큐먼트파일을 만들어서 각 각 server.c와 client.c 파일을 만들자.
그리고 아래의 내용을 각 각 복사 붙여넣기 하자.
아래의 소스 파일은 아래의 내용을 기본으로 한다.
designatedroom87.tistory.com/175?category=896511
클라이언트&서버 소켓 연결하기
C 프로젝트는 서버와 클라이언트 모두 각 각 따로 만든다. 서버 소켓을 만들 때, 프로젝트 이름을 server라하고 클라이언트 소켓을 만들 때는 프로젝트 이름을 client라고 하였다. 1. 서버 소켓 만들
designatedroom87.tistory.com
server.c
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
int main(void) {
struct sockaddr_in server_info; //주소 담는 구조체
int serverSocket; //서버 소켓번호
int clientSocket; //클라이언트 소켓
char sendBuff[1023];
serverSocket = socket(AF_INET,SOCK_STREAM,0); //서버소켓
if(serverSocket<1){ printf("socket fail\n"); return -1;}
//서버는 IP주소 PORT번호가 필요함.
//이 정보는 구조체에 담아 설정합니다.
memset(&server_info,'0',sizeof(server_info)); //memory init
server_info.sin_addr.s_addr = htonl(INADDR_ANY);
server_info.sin_port = htons(5555);
server_info.sin_family = AF_INET;
//소켓과 주소를 묶어주는 역할
bind(serverSocket,(struct sockaddr*)&server_info,sizeof(server_info));
printf("서버가 동작중입니다.\n");
memset(&sendBuff,'0',sizeof(sendBuff));
//대기
if(listen(serverSocket,10)==-1){
printf("listen fail\n"); return -1;
}
clientSocket = accept(serverSocket,(struct sockaddr*)NULL, NULL);
printf("클라이언트가 접속했습니다.\n");
//메시지 전달
strcpy(sendBuff,"hello");
//sprintf(sendBuff,"sensor:%d",rand()%1023);
write(clientSocket,sendBuff,strlen(sendBuff));
sleep(2);
close(clientSocket);
close(serverSocket);
return 0;
}
client.c
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
int main(void) {
int s;
struct sockaddr_in server_info;
char recvBuff[1024];
int state;
int size;
memset(&recvBuff,'0',sizeof(recvBuff));
s = socket(AF_INET, SOCK_STREAM, 0);
if(s<0){ printf("%d socket fail\n",s); return -1;}
server_info.sin_addr.s_addr = inet_addr("127.0.0.1");
server_info.sin_port = htons(5555);
server_info.sin_family = AF_INET;
printf("서버에 접속하려합니다.\n");
state=connect(s, (struct sockaddr*)&server_info, sizeof(server_info));
if (state ==-1) {
printf("서버에 접속할 수 없습니다.\n");
close(s);
return -1;
}
printf("서버에 정상적으로 접속했습니다.\n");
size=0;
//데이터 수신 작업
while((size=read(s,recvBuff,sizeof(recvBuff)-1))>0)
{
recvBuff[size]=0;
if(fputs(recvBuff,stdout)==EOF){printf("error 발생");}
}
close(s);
return 0;
}
그리고 다음과 같이 2개의 터미널 창의 띄우자.
그리고 리눅스의 각 각의 터미널 창에서 명령어를 각 각 다음과 같이 입력하자.
아래의 명령어는 각 c파일을 실행파일로 만든다.
gcc -o server server.c
gcc -o client client.c
명령어를 입력했을 때, 문구가 뜨지 않으면 에러가 없다는 의미이다.
그러면 HOME폴더에 아래와 같이 실행파일들이 만들어진다.
각 터미널 창에 다음과 같이 명령어를 입력하자.
아래의 명령어는 실행하는 명령어이다. 그러므로 서버를 먼저 실행시키도록 한다.
./server라고 먼저 입력하고
./client라고 입력한다.
다음과 같은 결과를 볼 수 있다.
그리고, client.c 파일에서 기존의 strcpy함수 문장을 주석처리하고
sprintf함수를 호출해보자. 그리고 반드시 세이브를 하자.
기존의 실행 중인 터미털 창에서 각 각 CTRL + C로 프로그램을 종료하자.
각 터미널 창에서 프로그램을 종료한 상태이다.
서버 쪽 터미널 창에서 다시 gcc -o server server.c 명령어를 입력하고 나서
서버 부터 실행시키자.
명령어는 각 각 ./server와 ./client 이다.
다음고 같은 결과를 얻을 수 있다.
아래는 서버가 계속 클라이언트 쪽으로 데이터를 보내서, 클라이언트 쪽이 데이터를 수신해서 출력하도록 만든 것인데
문제가 있다.
한참 뒤에, 클라이언트 쪽에서 데이터가 수신된다.
이유는 잘 모르겠다.
다만, 서버쪽에서 버퍼에 데이터를 계속 저장하다가 한 번에 보내는 것 같다.
프로그래밍에서 수정한 부분은 server.c에서만 수정했다.
데이터를 보내는 부분을 무한 루프로 감았다.