#include "smartsock2.h"
int main(int iRet, char *cpCmd[]) { int iSock; //socket 생성 struct sockaddr_in stAddr; //socket의 주소 //int iRet; //error 값은 저장한다. int iCSock[MAX_USER+1]; //새로운 소켓을 저장할 변수이다. unsigned int uiUser; socklen_t uiSockLen = sizeof(struct sockaddr); //unsigned int이다. char cBuffer[BUF_SIZE]; //echo서버를 위한 변수 char cMsg[MSG_SIZE]; fd_set fdRead; unsigned int uiCnt; unsigned int uiCnt2; int iMSock; char cNick[MAX_USER][NIC_NAME_SIZE]; unsigned short usPort = PORT;
if(2 == iRet) { iSock = atoi(cpCmd[1]); if(1024 < iSock) { if(65535 > iSock) { usPort = iSock; } } } printf("PORT: %d\n", usPort); iSock = socket(AF_INET, SOCK_STREAM, 0); //socket 생성 if(iSock < 0) //socket 에러 확인 { perror("socket() error : "); close(iSock); //리턴하기 전에 close도 해주어야한다. return 10; }
bzero(&stAddr, sizeof(stAddr)); //구조체를 지운다. stAddr.sin_family = AF_INET; // stAddr.sin_port = htons(usPort); //고정 PORT X stAddr.sin_addr.s_addr = inet_addr(IP); //고정 IP
iRet = bind(iSock, (struct sockaddr *)&stAddr, sizeof(stAddr)); if(iRet < 0) //bind 에러 확인 { perror("bind() error : "); close(iSock); //리턴하기 전에 close도 해주어야한다. return 15; }
iRet = listen(iSock, 5); if(iRet < 0) { perror("listen() error : "); close(iSock); //리턴하기 전에 close도 해주어야한다. return 20; } uiUser = 0; while(1) { FD_ZERO(&fdRead); FD_SET(0, &fdRead); FD_SET(iSock, &fdRead); iMSock = iSock; for(uiCnt = 0; uiCnt < uiUser ;++uiCnt) { FD_SET(iCSock[uiCnt], &fdRead); if(iMSock < iCSock[uiCnt]) { iMSock = iCSock[uiCnt]; } } select(iMSock+1, &fdRead, 0, 0, 0); if(0 != FD_ISSET(iSock, &fdRead)) { iCSock[uiUser] = accept(iSock, (struct sockaddr*)&stAddr, &uiSockLen); if(iCSock[uiUser] < 0) { perror("accept() error : "); continue; } if(MAX_USER <= uiUser) { read(iCSock[uiUser], cBuffer, NIC_NAME_SIZE); sprintf(cMsg, "Server is FULL."); write(iCSock[uiUser], cMsg, sizeof(cMsg)); write(iCSock[uiUser], MSG_END, sizeof(MSG_END)); close(iCSock[uiUser]); printf("Server is FULL : [%s]\n", cBuffer); printf("client IP : [%s]\n", inet_ntoa(stAddr.sin_addr)); //client IP continue; } read(iCSock[uiUser], cNick[uiUser], NIC_NAME_SIZE); printf("incoming client: [%s]\n", cNick[uiUser]); //누군가 접근중이다. printf("client IP : [%s]\n", inet_ntoa(stAddr.sin_addr)); //client IP write(iCSock[uiUser], "Welcome!", sizeof("Welcome!")); sprintf(cMsg, "[%s]님이 입장하셨습니다.", cNick[uiUser]); for(uiCnt2 = 0; uiCnt2 < uiUser ;++uiCnt2) { write(iCSock[uiCnt2], cMsg, MSG_SIZE); } ++uiUser; printf("%s\n", cMsg); }
if(0 != FD_ISSET(0, &fdRead)) { iRet = read(0, cBuffer, BUF_SIZE); if(0 == iRet) { for(uiCnt = 0; uiCnt < uiUser ;++uiCnt) { sprintf(cMsg, "Server is ENDING."); write(iCSock[uiCnt], cMsg, sizeof(cMsg)); write(iCSock[uiCnt], MSG_END, sizeof(MSG_END)); } break; } cBuffer[iRet-1] = 0; sprintf(cMsg, "공지사항: [%s]", cBuffer); for(uiCnt = 0; uiCnt < uiUser ;++uiCnt) { write(iCSock[uiCnt], cMsg, MSG_SIZE); } printf("%s\n", cMsg); }
for(uiCnt = 0; uiCnt < uiUser ;++uiCnt) { if(0 != FD_ISSET(iCSock[uiCnt], &fdRead)) { iRet = read(iCSock[uiCnt], cMsg, MSG_SIZE);
//if(0 == strncmp(MSG_END, cMsg+strlen(cNick[uiCnt])+2, strlen(MSG_END))) if( (0 == strncmp(MSG_END, cMsg, sizeof(MSG_END))) || (0 == iRet) ) { sprintf(cMsg, "[%s]님이 퇴장하셨습니다.", cNick[uiCnt]); close(iCSock[uiCnt]); --uiUser; iCSock[uiCnt] = iCSock[uiUser]; memcpy(cNick[uiCnt],cNick[uiUser], NIC_NAME_SIZE); } for(uiCnt2 = 0; uiCnt2 < uiUser ;++uiCnt2) { write(iCSock[uiCnt2], cMsg, MSG_SIZE); }
printf("%s\n", cMsg); } } }
for(uiCnt = 0; uiCnt < uiUser ;++uiCnt) { close(iCSock[uiCnt]); } close(iSock); // return 0; }
|