소켓 프로그래밍에서 bind error가 발생합니다.[수정 : 소스코드 추가]

ygt의 이미지

제목에 대략 함축을 다 했습니다. ㅡ.ㅡ;;

소켓 프로그래밍과 스레드를 사용해서 리눅스 환경에서 동작하는 간단한 채팅 프로그램을 만드는 과제가 있습니다 .

스레드 사용 기법을 찾다가 예제를 찾고 .. 예제가 잘 돌아가는걸 선배 노트북에서 확인했구요.

제가 거기다가 기능추가 간단한거 몇가지 좀 더해서 소스를 수정했는데

제 컴에서는 이게 돌리니까 서버가 소켓 바인드 할때 에러를 띄워버리네요.

처음엔 수정한 부분에 문제가 있나 싶었지만 소켓쪽에는 손댄게 없는데다가 원본인 예제를 가지고 컴파일하구 실행해봐도 바인드 에러가 나는 걸로 봐선 제 설정에 문제가 있는 것 같습니다.

참고로 잘 돌아갔던 선배도 엑스피에서 vmware로 우분투를 설치해서 테스트 한거였구요 인터넷은 제방의 무선 공유기 사용한 거였습니다.
(환경이 거의 유사...하다는 이야기죠. 음. 머가 문젤까)

급해서 제가 아는 곳중 답변이 나올만한 곳 두군데에 올려봅니다...;; 실례가 아니길 바라며 답변 감사히 받겠습니다.

/*
* 서버에게 강제 퇴장 권한을 부여
-> 처음으로 접속한 클라이언트에게 권한 부여
-> /kick ip

* 클라이언트에게 서버의 권한 일부를 위임
-> 다른 클라이언트에게 권함 위임 가능
-> /permission ip

* 클라이언트의 대화명의 변경 가능
-> 클라이언트가 name (array), sending name with message
-> /change name

* 클라이언트의 로그 인 시간과 로그 아웃 시간을 명시
-> 시간 함수
*/

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

#define BUFSIZE 100

void * clnt_connection(void *arg);
void send_message(char * message, int len);
void error_handling(char *message);

int master_permission = 0;

int clnt_number=0;
int clnt_socks[10];
char clnt_ip[10][20];
pthread_mutex_t mutx;

int main(int argc, char **argv)
{
int serv_sock;
int clnt_sock;
struct sockaddr_in serv_addr;
struct sockaddr_in clnt_addr;
int clnt_addr_size;
pthread_t thread;

time_t timer; //
struct tm *t; //

if(argc!=2)
{
printf("Usage : %s \n", argv[0]);
exit(1);
}

if(pthread_mutex_init(&mutx, NULL))
error_handling("mutex init error");

serv_sock=socket(PF_INET, SOCK_STREAM, 0);

memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family=AF_INET;
serv_addr.sin_addr.s_addr=htonl(INADDR_ANY);
serv_addr.sin_port=htons(atoi(argv[1]));

if(bind(serv_sock, (struct sockaddr*) &serv_addr, sizeof(serv_addr))==-1)
error_handling("bind() error"); //-> 문제의 에러 발생 부분

if(listen(serv_sock, 5)==-1)
error_handling("listen() error");

while(1)
{
clnt_addr_size=sizeof(clnt_addr);
clnt_sock=accept(serv_sock, (struct sockaddr*)&clnt_addr,&clnt_addr_size);

pthread_mutex_lock(&mutx);
clnt_socks[clnt_number]=clnt_sock;
strcpy(clnt_ip[clnt_number++],inet_ntoa(clnt_addr.sin_addr));
timer = time(NULL); // 현재 시각을 초 단위로 얻기
t = localtime(&timer); // 초 단위의 시간을 분리하여 구조체에 넣기
pthread_mutex_unlock(&mutx);

pthread_create(&thread, NULL, clnt_connection, (void*)clnt_sock);
printf("새로운 연결, 클라이언트 IP : %s \n", inet_ntoa(clnt_addr.sin_addr));
printf("접속 시간 %d월 %d일 %d:%d:%d\n",t->tm_mon+1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
}

return 0;
}

void * clnt_connection(void *arg)
{
int clnt_sock= (int)arg;
int str_len=0;
char message[BUFSIZE];
char operation[20], ip[20], tmp[256];

int i, master=-1;

time_t timer; //
struct tm *t; //

while( (str_len=read(clnt_sock, message, sizeof(message))) != 0)
{
if (message[0] == '/') //추방 & 권한위임 설정
{
//일단 권한이 있어야 한다. 없으면 백
for (i=0;i {
if (clnt_sock == clnt_socks[i])
{
master = i;
break;
}
}
if (master != master_permission)
{
sprintf(tmp,"***명령 실패 : 권한이 없습니다.\n");
send_message(tmp, strlen(tmp));
continue;
}

//권한이 있는 경우

sscanf(message,"%s %s",operation,ip); //명령어 추출
if (!strcmp(operation,"/permission"))
{
pthread_mutex_lock(&mutx);
for (i=0;i {
if (!strcmp(ip,clnt_ip[i])) //입력된 아이피가 일치하면
{
master_permission = i;
sprintf(tmp,"***방장 변경 : %s***\n",ip);
send_message(tmp, strlen(tmp));
break;
}
}
if ( i == clnt_number )
{
sprintf(tmp,"***방장 변경 실패 : 찾을 수 없는 ip\n");
send_message(tmp, strlen(tmp));
}
pthread_mutex_unlock(&mutx);
}
else if (!strcmp(operation,"/kick"))
{
pthread_mutex_lock(&mutx);
for (i=0;i {
if (!strcmp(ip,clnt_ip[i])) //입력된 아이피가 일치하면
{
timer = time(NULL); // 현재 시각을 초 단위로 얻기
t = localtime(&timer); // 초 단위의 시간을 분리하여 구조체에 넣기
sprintf(tmp,"***추방 : %s***\n",ip);
send_message(tmp, strlen(tmp));

close(clnt_socks[i]);

for( ; i {
clnt_socks[i]=clnt_socks[i+1];
strcpy(clnt_ip[i],clnt_ip[i+1]);
}
clnt_number--;
}
}
if ( i == clnt_number )
{
sprintf(tmp,"***추방 실패 : 찾을 수 없는 ip\n");
send_message(tmp, strlen(tmp));
}
pthread_mutex_unlock(&mutx);
}
//권한이 있는 경우 종료
}
else //그외의 단순 메시지 출력
send_message(message, str_len);
}
//읽기 쓰기 루프 종료


pthread_mutex_lock(&mutx);
timer = time(NULL); // 현재 시각을 초 단위로 얻기
t = localtime(&timer); // 초 단위의 시간을 분리하여 구조체에 넣기
for(i=0; i {
if(clnt_sock == clnt_socks[i])
break;
}
printf("연결 종료, 클라이언트 IP : %s \n",clnt_ip[i]);
printf("종료 시간 %d월 %d일 %d:%d:%d\n",t->tm_mon+1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);

/* 나간 클라이언트 밀어서 정리하기 */
for( ; i {
clnt_socks[i]=clnt_socks[i+1];
strcpy(clnt_ip[i],clnt_ip[i+1]);
}
clnt_number--;
pthread_mutex_unlock(&mutx);

close(clnt_sock);
return 0;
}


void send_message(char * message, int len)
{
int i;
pthread_mutex_lock(&mutx);
for(i=0; i write(clnt_socks[i], message, len);
pthread_mutex_unlock(&mutx);
}

void error_handling(char *message)
{
fputs(message, stderr);
fputc('\n', stderr);
exit(1);
}

ygt의 이미지

일시적으로 인터넷 연결이 불안해져서 여러번 클릭한 탓에 글이 중복되어 올라왔는데 삭제 버튼이 쉽게 보이지가 않네요 ;;

수정추가 : 편집에서 지울수 있네요 중복된 같은 글 3개는 지우고 한개만 남겼습니다.

linehat의 이미지

된다 안된다를 떠나서 에러메시지라도 알려주셔야 여기분들이 짐작이라도 할텐데..

myohan의 이미지

비정상? 종료상황이 있었던것 인가 ...
아래의 옵션을 적용해 보세요 ~

setsockopt(listen_sd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));

---------------------------------------
blog : http://myohan.egloos.com

---------------------------------------
blog : http://myohan.egloos.com

송지석의 이미지

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.