간단한 채팅서버 플그램인데여...

익명 사용자의 이미지

안냐세여..

아래는 간단한 멀티채팅서버 플그램인데여...

클라이언트가 접속해 있는 상황에선 메세지 전달이 잘 되더라구여..

근데 접속한 클라이언트중 하나가 접속이 끊기면 파이프가 깨어지는 현상
이 생기더라구여..

뭣때문에 그런지 도무지 알수가 없더라구여..(워낙 허접해서리...-_-ㆀ)

혹 원인을 아시는분은 답변 부탁드립뉘다...

#####################################################################
#include
#include
#include
#include
#include
#include
#include

#define MAXLINE 1024
#define MAX_SOCK 512

char *escapechar = "exit\n";
int readline(int, char *, int);

int main(int argc, char *argv[]) {
char rline[MAXLINE], my_msg[MAXLINE];
char *start = "대화방에 오신걸 환영합니다...\n";
int i, j, n;
int s, client_fd, clilen;
int nfds; /* 최대 소켓번호 +1 */
fd_set read_fds; /* 읽기를 감지할 소켓번호 구조체 */
int num_chat = 0; /* 채팅 참가자 수 */
/* 채팅에 참가하는 클라이언트들의 소켓번호 리스트 */
int client_s[MAX_SOCK];
struct sockaddr_in client_addr, server_addr;

if(argc < 2) {
printf("실행방법 %s 포트번호\n",argv[0]);
return -1;
}

printf("대화방 서버 초기화 중....\n");

/* 초기소켓 생성 */
if((s = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
printf("Server Can't open stream socket.");
return -1;
}

/* server_addr 구조체의 내용 세팅 */
bzero((char *)&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons(atoi(argv[1]));

if (bind(s,(struct sockaddr *)&server_addr,sizeof(server_addr)) <
0) {
printf("Server Can't bind local address.\n");
return -1;
}

/* 클라이언트로부터 연결요청을 기다림 */
listen(s, 5);

nfds = s + 1; /* 최대 소켓번호 +1 */
FD_ZERO(&read_fds);

while(1) {
/* (최대 소켓번호 +1) 값을 갱신 */
if((num_chat-1) >= 0) nfds = client_s[num_chat-1] + 1;

/* 읽기 변화를 감지할 소켓번호를 fd_set 구조체에 지정 */
FD_SET(s, &read_fds);
for(i=0; i
/*--------------------------------------- select() 호출 -
---------------------------------------- */
if (select(nfds, &read_fds, (fd_set *)0, (fd_set *)0,(struct
timeval *)0) < 0) {
printf("select error\n");
return -1;
}
/*------------------------------ 클라이언트 연결요청 처
리 ------------------------------- */
if(FD_ISSET(s, &read_fds)) {
clilen = sizeof(client_addr);
client_fd = accept(s, (struct sockaddr *)
&client_addr, &clilen);

if(client_fd != -1) {
/* 채팅 클라이언트 목록에 추가 */
client_s[num_chat] = client_fd;
num_chat++;
send(client_fd, start, strlen(start), 0);
printf("%d번째 사용자 추가.\n",num_chat);
}
}

/*------ 임의의 클라이언트가 보낸 메시지를 모든 클라이언트에게
방송 ----- */
for(i = 0; i < num_chat; i++) {
if(FD_ISSET(client_s[i], &read_fds)) {
if((n = recv(client_s[i], rline, MAXLINE,0)) > 0)
{
rline[n] = '\0';

/* 종료문자 입력시 채팅 탈퇴 처리 */
// if(!sock)
if (exitCheck(rline, escapechar, 5) == 1) {
shutdown(client_s[i], 2);
if(i != num_chat-1) client_s[i] =
client_s[num_chat-1];
num_chat--;
continue;
}

/* 모든 채팅 참가자에게 메시지 방송 */
for (j = 0; j < num_chat; j++) send(client_s
[j], rline, n, 0);
printf("%s", rline);
}
}
}
}
}

/* ------------------------------- 종료문자 확인 함수 ---------------
-------------
exitCheck()는 다음의 세 개의 인자를 필요로 한다
rline 클라이언트가 전송한 문자열 포인터
escapechar 종료문자 포인터
len 종료문자의 크기
---------------------------------------------------------------------
------------------------*/
int exitCheck(rline, escapechar, len)
char *rline; /* 클라이언트가 전송한 메시지 */
char *escapechar; /* 종료문자 */
int len;
{
int i, max;
char *tmp;

max = strlen(rline);
tmp = rline;
for(i = 0; i if (*tmp == escapechar[0]) {
if(strncmp(tmp, escapechar, len) == 0)
return 1;
} else
tmp++;
}
return -1;
}

#####################################################################

익명 사용자의 이미지

클라이언트 접속 종료는 특정 값을 주고 받을 필요없이
recv()의 리턴값이 0인 것으로 판단하면 됩니다.
그렇게 해도 되는게 아니고 그렇게 해야 하는 겁니다.
이유는 생각해 보시면 알 수 있습니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.