티스토리 뷰

IT/Visual Studio

[C언어] 계산기 프로그램

미닉길 2014. 10. 25. 09:55
반응형

올해 1학기에 네트워크 프로그래밍 수업을 들었었는데요.

그때 실행했던 소스를 공유차 올립니다.


서버 소스


#include <stdio.h>
#include <winsock2.h>
#define  MSG_SIZE 1024
#define  OpndSize 4

#pragma comment(lib,"ws2_32.lib")


void PrintErrorMsg( char *msg)
{
 printf("<ERROR> - %s \n", msg);
 exit(0);
}
int Calculate( int opndCnt, int opnds[], char op );
int main(void)
{
 WSADATA   wsa;
 int    ret, opndCnt, result, clntAdrSize;
 SOCKET   hSocket;
 SOCKADDR_IN  servAdr, clntAdr;
 char   msg[ MSG_SIZE ];

 // 1. 소켓 라이브러리 초기화 하기.
 ret = WSAStartup( MAKEWORD(2,2), &wsa );
 if( ret != 0){
  PrintErrorMsg("소켓 라이브러리 초기화 실패");
 }
 
 // 2. 소켓 생성하기.
 hSocket = socket( PF_INET, SOCK_DGRAM, 0 );
 if( hSocket == INVALID_SOCKET ) {
  PrintErrorMsg("소켓 생성 오류 발생");
 }

 // 3. 주소 구조체 설정하기.
 memset( &servAdr, 0, sizeof(servAdr) );
 servAdr.sin_family  = AF_INET;
 servAdr.sin_port  = htons(9000);
 servAdr.sin_addr.s_addr = inet_addr("127.0.0.1");

 // 4. 주소를 소켓에 설정하기
 ret = bind( hSocket, (SOCKADDR *)&servAdr, sizeof(servAdr) );
 if( ret == SOCKET_ERROR ){
  PrintErrorMsg("소켓 주소 설정 오류 발생");
 }

 // 5. 클라이언트로부터 msg를 수신해서 계산 수행하고, 결과 전송하기.
 clntAdrSize = sizeof(clntAdr);
 while(1)
 {
  // 5.1. 클라이언트로부터 msg 수신 대기.
  printf("> 클라이언트로부터 계산 요청을 기다리고 있습니다.\n");

  // 5.2. msg 수신
  recvfrom( hSocket, msg, MSG_SIZE, 0, (SOCKADDR *)&clntAdr, &clntAdrSize );

  // 5.3. 피연산자 갯수 저장하기.
  opndCnt = msg[0];

  // 5.4. 계산하기.
  result = Calculate( opndCnt, (int *)&msg[1], msg[ opndCnt*OpndSize +1] );

  // 5.5. 결과 보내기
  sendto( hSocket, (char *)&result, sizeof(result), 0, (SOCKADDR *)&clntAdr, sizeof(clntAdr) );
  printf("> 결과 %d를 전송했습니다.\n", result);
 }
  
 // 소켓 종료
 closesocket(hSocket);
 
 // 소켓 라이브러리 종료하기.
 WSACleanup();
 return 0;
}

int Calculate( int opndCnt, int opnds[], char op )
{
 int result, index;
 result = opnds[0];

 for( index=1; index<opndCnt; index++)
 {
  switch( op )
  {
  case '+': result += opnds[index];
   break;
  case '*': result *= opnds[index];
   break;
  case '-': result -= opnds[index];
   break;
  }
 }
 return result;
}



클라이언트


#include <stdio.h>
#include <winsock2.h>
#define  MSG_SIZE 1024
#define  OpndSize 4
void PrintErrorMsg( char *msg)
{
 printf("<ERROR> - %s \n", msg);
 exit(0);
}

int main(void)
{
 int    ret, opndCnt, index, result, servAdrSize;
 SOCKET   hSocket;
 SOCKADDR_IN  servAdr;
 char   msg[ MSG_SIZE ];
 WSADATA   wsa;

 // 1. 소켓 라이브러리 초기화 하기.
 ret = WSAStartup( MAKEWORD(2,2), &wsa );
 if( ret != 0 ) {
  PrintErrorMsg("소켓 라이브러리 초기화 오류");
 }

 // 2. 소켓 생성하기.
 hSocket = socket( PF_INET, SOCK_DGRAM, 0 );
 if( hSocket == INVALID_SOCKET ) {
  PrintErrorMsg("소켓 생성 실패");
 }

 // 3. 주소 구조체 설정하기.
 memset( &servAdr, 0, sizeof(servAdr) );
 servAdr.sin_family  = AF_INET;
 servAdr.sin_port  = htons(9000);
 servAdr.sin_addr.s_addr = inet_addr("127.0.0.1");
 
 // 4. 계산 파라메터 입력하기.
 // 4.1. 피연산자 개수 입력하기.
 printf("> 피연산자의 갯수를 입력하세요 : ");
 scanf("%d", &opndCnt );
 msg[0] = opndCnt;

 // 4.2. 피연산자를 opndCnt 수 만큼 읽어들여 msg에 저장하기.
 for( index=0; index<opndCnt; index++ ) {
  printf("> %d번째 피연산자를 입력하세요 : ", index+1);
  scanf("%d", (int *)&msg[ index*OpndSize + 1 ] );
 }
 fgetc(stdin); // 마지막 자리에 엔터를 제거...

 // 4.3. 연산자를 읽어들여 msg에 저장하기.
 printf("> 연산자를 입력하세요 : ");
 scanf("%c", &msg[ opndCnt*OpndSize + 1 ] );

 // 5. msg 를 서버로 전송하기.
 sendto( hSocket, msg, sizeof(msg), 0, (SOCKADDR *)&servAdr,sizeof(servAdr) ); /* 0은 플래그값 */
 printf("> 메시지를 전송하였습니다. \n> 서버로부터 결과를 기다리고 있습니다\n");

 // 6. 서버로부터 결과 수신하기.
 servAdrSize = sizeof(servAdr);
 recvfrom( hSocket, (char *)&result, sizeof(result), 0, (SOCKADDR *)&servAdr, (int *)&servAdrSize);
 printf("> 계산된 결과는 %d입니다. \n", result);

 // 7. 소켓 종료
 closesocket(hSocket);

 // 소켓 라이브러리 종료하기.
 WSACleanup();
 return 0;
}

반응형

'IT > Visual Studio' 카테고리의 다른 글

OpenCV 2.1 버전 설치하기 ( VS 2008 )  (0) 2015.07.06
댓글
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함