연결형 서버/클라이언트 예제 (클라이언트 포함)

System Program/socket 2014. 3. 6. 15:37

1. 서버 프로그램

 

클라이언트로부터 송신한 문자열을 stdout에 단지 출력한다.

 

서버에서는 accept()함수로부터 단지 하나의 새로운 소켓 디스크립터를 할당 받고

이 파일 디스크립터를 이용하여 클라이언트로부터 문자열을 받는다.

즉, 멀티프로세스, 멀티쓰레드 구현이 아니다. 이를 구현하기 위해서는

accept()함수로 계속적으로 새로운 소켓 파일 디스크립터를 생성받고 새로운 프로세스나 새로운 쓰레드를

통해서 다른 추가적인 작업 후 종료하는 방식으로 작성되야 할 것이다.

 

/*
* main.c -- C Test App.
*
* Copyright (C) 2012-2013, 2013 heesoon.kim <chipmaker.tistory.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/socket.h>

#define READ_MAX_LEN 128

int main(int argc, char *argv[])
{
	int sockfd, acceptfd;
	ssize_t nread;
	struct sockaddr_in server_addr, client_addr;
	socklen_t server_addrlen, client_addrlen = 0;
	char buffer[READ_MAX_LEN] = {0};
	
	server_addr.sin_family = AF_INET;
	server_addr.sin_addr.s_addr = inet_addr("192.168.0.2");
	//server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
	server_addr.sin_port = htons(5000);
	
	server_addrlen = sizeof(server_addr);
	
	sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if(sockfd < 0)
	{
		perror("socket : ");
		exit(EXIT_FAILURE);
	}
	
	if(bind(sockfd, (struct sockaddr *)&(server_addr), server_addrlen) < 0)
	{
		perror("bind : ");
		exit(EXIT_FAILURE);	
	}
	
	if(listen(sockfd, 5) < 0)
	{
		perror("listen : ");
		exit(EXIT_FAILURE);	
	}
	
	acceptfd = accept(sockfd, (struct sockaddr *)&(client_addr), &client_addrlen);
	if(acceptfd < 0)
	{
		perror("listen : ");
		exit(EXIT_FAILURE);	
	}	

	while(1)
	{
		memset(buffer, 0, READ_MAX_LEN);
		nread = read(acceptfd, buffer, READ_MAX_LEN);
		if(nread == -1)
		{
			perror("read : ");
			exit(EXIT_FAILURE);	
		}
			
		write(STDOUT_FILENO, buffer, strlen(buffer));
		
		if(strncmp(buffer, "bye", 3) == 0)
		{
			close(acceptfd);
			break;		
		}
	}
	
	close(sockfd);
	printf("exit process \n");
	exit(EXIT_SUCCESS);
}


 

2. 클라이언트 프로그램

 

단지 문자열을 서버단으로 전송하는 작업만을 수행한다.

 

/*
* main.c -- C Test App.
*
* Copyright (C) 2012-2013, 2013 heesoon.kim <chipmaker.tistory.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/socket.h>

#define WRITE_MAX_LEN 128

int main(int argc, char *argv[])
{
	int sockfd;
	ssize_t nread = 0;
	char buffer[WRITE_MAX_LEN] = {0};	
	struct sockaddr_in ServerAddr;	
	
	ServerAddr.sin_family = AF_INET;
	ServerAddr.sin_addr.s_addr = inet_addr("192.168.0.2");
	ServerAddr.sin_port = htons(5000);
	
	sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if(sockfd < 0)
	{
		perror("socket : ");
		exit(EXIT_FAILURE);
	}
	
	if(connect(sockfd, (struct sockaddr *)&(ServerAddr), sizeof(ServerAddr)) == -1)
	{
		perror("connect : ");
		exit(EXIT_FAILURE);
	}	
	
	while(1)
	{	
		memset(buffer, 0x00, WRITE_MAX_LEN);
		puts("input message : ");
		
		nread = read(STDIN_FILENO, buffer, WRITE_MAX_LEN /* SSIZE_MAX -1 */);
		if(nread == -1)
		{
			perror("read : ");
			exit(EXIT_FAILURE);
		}		

		if(write(sockfd, buffer, (size_t)nread) < 0)
		{
			perror("write : ");
			exit(EXIT_FAILURE);
		}

		if(strncmp(buffer, "bye", 3) == 0)
			break;		
	}
	
	close(sockfd);
	printf("exit process \n");
	exit(EXIT_SUCCESS);
}


 

'System Program > socket' 카테고리의 다른 글

연결형 에코 서버 예제  (0) 2014.03.06
소켓옵션  (0) 2014.03.05
IP주소 및 포트 정보관련 시스템 함수  (0) 2014.03.04
IP주소 및 포트 관리  (0) 2014.03.04
주소 구조체  (0) 2014.03.04
: