소켓에서 bind() 가..되다 안되다...

elfs의 이미지

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>


int main(int argc, char **argv){

		//sd server descripter
		int sd;
		//cd client ....
		int cd;

		int bind_result;

		
		char *port;
		
	  	struct sockaddr_in	s_addr;
	    struct sockaddr_in	c_addr;	
		int cd_size;

		char s_message[] = "서버에서 보내는 메세지 입니다.";
		
		port = "3333";
		// 소켓 디스크립터 생성.//////////////////////////////////////////////////	
		if((sd = socket(PF_INET,SOCK_STREAM,IPPROTO_TCP)) == -1 ){
			printf("소켓생성 오류\n");
			exit(1);
		}
		printf("소켓성생완료...소켓의 디스크립터번호는 %d 입니다.\n",sd);

		
		// 서버주소 할당. ////////////////////////////////////////////////////////
		memset(&s_addr,0,sizeof(s_addr)); //메모리 주소 초기화
		s_addr.sin_family = AF_INET; //ipv4 프로토콜 , AF_INET6 = ipv6, AF_LOCAL = local통신용(프로세스간의)
		s_addr.sin_addr.s_addr = htonl(INADDR_ANY);  // INADDR_ANY 는 시스템의 아이피.
		s_addr.sin_port = htons(atoi(port));		 // 포트할당.
	



		//bind() 소켓에 할당된 주소를 맵핑한다. //////////////////////////////////
		bind_result = bind(sd,(struct sockaddr*)&s_addr,sizeof(s_addr));

		if(bind_result == -1){
			printf("bind() 할당오류..\n");
			exit(1);
		}
		printf("bind() 할당 성공.\n");

		///////////////////////////////////////////////////////////////////////////
		// listen() 에서 대기한다.
		if( listen(sd,15) == -1){
			printf("listen() error\n");
			exit(1);
		}
		printf("listen 대기중..\n");
		///////////////////////////////////////////////////////////////////////////
		// accept 로 클라이언트의 연결을 받아들인다.
		if((cd = accept(sd,(struct sockaddr*)&c_addr,&cd_size)) == -1){
			printf("accept error\n");
			exit(1);
		}
		printf("클라이언트 파일 디스크립터의 주소는 %d 에 할당되었습니다.\n",cd);
		//////////////////////////////////////////////////////////////////////////
		//
		write(cd,s_message,sizeof(s_message));
		printf("클라이언트에 메세지 전송 : %s\n",s_message);

		printf("클라이언트 소켓종료..");
		close(cd);	


		close(sd);
		printf("소켓종료..\n");
		return 0;
}

이 소스로 프로그램을 실행시켜서 보면 처음에 한번은 잘 돕니다.
그리고 나서 다시 실행시키면 bind() 오류가 납니다.
그러다가 한참 있다가 돌리면 또 됩니다.
ps aux 로 확인해보면 프로세스는 잘 죽어있구요..
다시 그 포트로 접속해도 접속도 되지 않습니다.
이유가 무엇인지요..? -.-

Quote:
[root@cherry socket]# sz server.c
둖O[root@cherry socket]# ./a.out
소켓성생완료...소켓의 디스크립터번호는 3 입니다.
bind() 할당 성공.
listen 대기중..
클라이언트 파일 디스크립터의 주소는 4 에 할당되었습니다.
클라이언트에 메세지 전송 : 서버에서 보내는 메세지 입니다.
클라이언트 소켓종료..소켓종료..
[root@xxxxx socket]# ./a.out
소켓성생완료...소켓의 디스크립터번호는 3 입니다.
bind() 할당오류..
[root@xxxxx socket]# ./a.out
소켓성생완료...소켓의 디스크립터번호는 3 입니다.
bind() 할당오류..
[root@xxxxx socket]# ./a.out
소켓성생완료...소켓의 디스크립터번호는 3 입니다.
bind() 할당오류..
[root@xxxxx socket]#

1분정도 후에 실행하면

Quote:
[root@xxxxx socket]# ./a.out
소켓성생완료...소켓의 디스크립터번호는 3 입니다.
bind() 할당 성공.
listen 대기중..

또 잘 됩니다..

sozu의 이미지

elfs wrote:
		
		char *port;
	
		port = "3333";
		s_addr.sin_port = htons(atoi(port));

왜 바인딩이 되었다가 않되었다가 하는지는 잘모르겠지만
살짝 틀린 코드가 아닌가요?^^;

char *port = "3333";
s_addr.sin_port = htons(atoi(port));

이렇게나..

short port = 3333;
s_addr.sin_port = htons(port);

이렇게 하셔야 하지 않을까요 :D

-----------
청하가 제안하는 소프트웨어 엔지니어로써 재미있게 사는 법
http://sozu.tistory.com

FruitsCandy의 이미지

소켓 옵션 설정을 하시면 됩니다.

소켓이 내려가도 해당포트를 바로 바인딩 할 수 있는게 아닙니다.

port reuse 인가? sock reuse 인가 하는 옵션이 있습니다.

설정하시면 소켓 죽이고 살릴때마다 바로 바인딩 됩니다.

아지랑이류 초환상 공콤 화랑... 포기하다.. T.T

elfs의 이미지

FruitsCandy wrote:
소켓 옵션 설정을 하시면 됩니다.

소켓이 내려가도 해당포트를 바로 바인딩 할 수 있는게 아닙니다.

port reuse 인가? sock reuse 인가 하는 옵션이 있습니다.

설정하시면 소켓 죽이고 살릴때마다 바로 바인딩 됩니다.

저기..조금만 더 쉽게 설명을 부탁드려도 될런지요.. :oops:
어디서 그걸 조절하는거지요?

FruitsCandy의 이미지

int setsockopt (
SOCKET s,
int level,
int optname,
const char FAR * optval,
int optlen
);

setsockopt(
Socket,
SOL_SOCKET,
SO_REUSEADDR , <--- 이것입니다.
&optval,
sizeof(optval)
);.

자세한 설명은 man 페이지 참조하세요 . 죄송..:)

아지랑이류 초환상 공콤 화랑... 포기하다.. T.T

june의 이미지

tcp로 통신을 할때.. TIME-WAIT 라는 것이 있습니다.
데이터가 완전히 전송되지 않았는데 통신이 두절(?)되는것을 막기위한
방법이죠. 즉 사용자가 서버를 죽였더라도 지들이 좀더 생명을 연장한다고 할까요? (TIME-WAIT로 검색해보세요..)

음.. 이걸 죽이는 옵션이 있는데요

SO_REUSEADDR 이라고 합니다.이게 디폴트 값이 0인데, 이걸 1로 바꿔주면
바로바로 소켓에 주소가 할당되고 또 사라졌다가 다시 할당됩니다..

커피는 블랙이나 설탕만..

emptysky의 이미지

time-wait 의 디폴트 시간은 약 45초 입니다.
"Address already in use"
에러문을 보았다면 윗분말씀대로 SO_REUSEADDR 소켙 옵션을 주시던가 45초 이 후 실행하면 문제를 해결하실수 있을겁니다.

『 아픔은.. 아픔을 달래줄 약이 무엇인지 알면서도 쓰지 못할 때 비로소 그 아픔의 깊이를 알수가 있음이다. 』
『 for return...』

댓글 달기

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