LINUX(우분투)

간단한 소켓 통신

DesignatedRoom 2021. 1. 11. 09:10

리눅스에서 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에서만 수정했다.

데이터를 보내는 부분을 무한 루프로 감았다.

server.c
0.00MB
client.c
0.00MB