쓰레드 수업 후 교수님께서 내준 과제.
서버와 클라이언트 상호간 통신을 하는 프로그램을 만들되, 서버는 들어오는 소켓을 쓰레드를 이용하여
생성하여야 하는 것이 조건.
구현 언어는 C, 컴파일하는 OS는 리눅스 기반에서 해야 함.
소켓 프로그래밍은 사실 한번도 공부한 적이 없어서 코딩하기가 굉장히 힘들었다.
교보문고를 수없이 왔다갔다 하고 몇시간을 구글링해서 자료를 모아서 소켓 프로그래밍의 개념을 익힌 뒤
코딩을 했다.
때문에 개발 기간이 일주일 씩이나 걸렸고, 코딩을 이틀 밤을 꼬박 새서 겨우 완성했다.
클라이언트에서 /TIME 명령어를 서버로 전송했을 때 현재 시간을 응답하던 그 순간 얼마나 기쁘던지.ㅋ
여튼 무쟈게 힘들었지만 이번 기회로 소켓 프로그래밍을 본격적으로 공부해 보는 계기가 되었으니 좋긴 하다.
프로그램은 서버와 클라이언트를 실행 시킨 뒤, 클라이언트에서 /TIME 명령어를 입력하면
서버에서 현재 시간을 알려주는 기능을 한다.
주석을 쓰려다가 워낙 바빠서 미처 주석을 쓰지 못했다.
하지만 따라가다보면 그닥 어렵진 않을 것이다.
그럼 소스를 공개함 ㅇㅇ
//Server.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <pthread.h>
#include <time.h>
#include <arpa/inet.h>
#include <sys/types.h>
#define PORT 8010
void *thread_time(void *time);
struct tm *tm_ptr;
main(int argc, char *argv[])
{
int connect_sock, listen_sock;
int len;
struct sockaddr_in se_addr, cl_addr;
pthread_t pthread1;
listen_sock = socket(PF_INET, SOCK_STREAM, 0);
memset(&se_addr, 0, sizeof(se_addr));
se_addr.sin_family = AF_INET;
se_addr.sin_port = htons(PORT);
se_addr.sin_addr.s_addr = htonl(INADDR_ANY);
// struct define
if(bind(listen_sock, (struct sockaddr *) &se_addr, sizeof(se_addr)) == 1)
{
printf("Can't Bind\n");
return -1;
}
if(listen(listen_sock, 5) == -1){
printf("no listen\n");
return -1;
}
len = sizeof(cl_addr);
if((connect_sock = accept(listen_sock, (struct sockaddr *) &cl_addr, &len)) == -1) {
printf("not accept\n");
}
pthread_create(&pthread1, NULL, thread_time, (void *) &connect_sock);
pthread_join(pthread1, NULL);
close(listen_sock);
return 0;
}
void *thread_time(void* time1)
{
char rcvBuffer[255];
char buffer[255];
time_t the_time;
the_time = time(NULL);
memset(buffer,0,255);
int connect_sock = *((int*) time1);
read(connect_sock, rcvBuffer, strlen(rcvBuffer));
if(strncmp(rcvBuffer, "/TIME",5))
{
tm_ptr = localtime(&the_time);
sprintf(buffer, "%d-%d-%d %d:%d\n", tm_ptr->tm_year +1900,
tm_ptr->tm_mon +1, tm_ptr->tm_mday, tm_ptr->tm_hour,
tm_ptr->tm_min);
}
else if(!strcmp(rcvBuffer, "quit"))
{
}
write(connect_sock, buffer, strlen(buffer));
}
//Client.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <netinet/in.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#define PORT 8010
int main(int argc, char *argv[]) {
int connecting_sock;
struct sockaddr_in connect_addr;
int leng;
char sndBuffer[255], rcvBuffer[255];
connecting_sock = socket(PF_INET, SOCK_STREAM, 0);
//socket define
memset(&connect_addr, 0, sizeof(connect_addr));
connect_addr.sin_family = AF_INET;
connect_addr.sin_addr.s_addr = inet_addr(argv[1]);
connect_addr.sin_port = htons(PORT);
if(connect(connecting_sock,/*socket*/ (struct sockaddr *) &connect_addr,/*server address information pointer */ sizeof(connect_addr)) == -1) {
// socket -> server connect request!
printf("Can't connect\n");
close(connecting_sock);
return -1;
}
memset(sndBuffer,0,255);
printf("input '/TIME'\n");
fputs("('quit' => End)\n", stdout);
fgets(sndBuffer, sizeof(sndBuffer) , stdin);
if(!strncmp(sndBuffer, "quit", 4))
exit(0);
write(connecting_sock, sndBuffer, strlen(sndBuffer));
leng = read(connecting_sock, rcvBuffer, sizeof(rcvBuffer)-1);
printf("%s\n", rcvBuffer);
close(connecting_sock);
}
'공대남자 > 프로그래밍' 카테고리의 다른 글
데이터베이스 개론 기본개념 정리 (0) | 2010.05.03 |
---|---|
Process Synchronization, Deadlock (0) | 2010.04.12 |
프로세스 동기화 시험전 잠깐 정리 (0) | 2010.03.31 |
운영체제 - 멀티 프로세스 생성하고 실행하는 프로그램 (0) | 2010.03.20 |
운영체제 - 1. Introduction of Operating System (0) | 2010.03.08 |