본문 바로가기

과제모음

Select함수를 이용한 1:1 채팅(Server)

반응형
#include <winsock2.h>
#include <stdio.h>      
#include <stdlib.h>     
#include <string.h>     
#include <conio.h>
#include <time.h>
#include <sys/types.h>

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

void ErrorHandling(char *message) // 에러메시지 출력함수
{
printf(message);
exit(0);
}

int main()
{
WSADATA wsaData; // 소켓 변수 선언
SOCKET serverSocket;
SOCKET clientSocket;
SOCKADDR_IN servAddr;
SOCKADDR_IN clntAddr;
unsigned int clntLen=0;
char chatdata[65536];
fd_set read_fds; // 셀렉트함수 사용
struct timeval time = {0,0}; // 시간설정
int recvn;
if(WSAStartup(MAKEWORD(2,2),&wsaData)!=0) // 소켓 생성 및 연결
ErrorHandling("WSAStartup() error!");

serverSocket = socket(PF_INET, SOCK_STREAM, 0); // 셀렉트 함수 사용위해 PF선언
if(serverSocket == INVALID_SOCKET)
ErrorHandling("socket() error");

memset(&servAddr,0,sizeof(servAddr)); // 소켓의 각 값들을 지정
servAddr.sin_family = AF_INET;
servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
servAddr.sin_port = htons(3000);

if(bind(serverSocket,(SOCKADDR*)&servAddr,sizeof(servAddr))==SOCKET_ERROR)
{
ErrorHandling("bind() error");
}

//접속대기
if(listen(serverSocket,5)==SOCKET_ERROR)
ErrorHandling("listen() error");

//연결수락
clntLen = sizeof(clntAddr);
clientSocket = accept(serverSocket,(SOCKADDR*)&clntAddr,&clntLen);
if(clientSocket==INVALID_SOCKET)
ErrorHandling("accept() error");
else
printf("\nHandling client %s\n", inet_ntoa(clntAddr.sin_addr));


while(1)
{
FD_ZERO(&read_fds); // 파일디스크립터 초기화
FD_SET(clientSocket,&read_fds);
select(5, (fd_set*)&read_fds, NULL, NULL, &time); // 일성 시간마다 파일디스크립터값을 읽어옴
// 파일 디스크립터의 값을 읽어와 소켓으로 받도록 한다
if(FD_ISSET(clientSocket,&read_fds)) { // 클라이언트 입력 데이터를 받아서 출력
recvn = recv(clientSocket,chatdata,sizeof(chatdata),0);
if(recvn < 0){
ErrorHandling("recv Error\n");
}
printf("Client : %s\n",chatdata); // 받은 데이터를 출력한다
}
if(kbhit()) // 키보드가 입력중이면
{
printf("Send Message : ");
gets(chatdata); // 클라이언트로 보낼 메시지 입력
send(clientSocket,chatdata,sizeof(chatdata),0);
printf("Server : %s\n",chatdata);
}
if(strcmp(chatdata, "exit") == 0 ){ // 종료 명령어
break;
}
memset(chatdata,0,sizeof(chatdata)); // 입력값 초기화

}

closesocket(clientSocket); // 연결종료
WSACleanup();
return 0;
}
반응형