FreeBSD에서 socket 생성시 에러가 안납니다.

bugiii의 이미지

안녕하세요?

FreeBSD에서 socket을 생성하는데 미리 열려진 것을 포함해서 1024개 이상을 만들 때, (개수 제한 푸는 문제가 아니구요) 분명히 -1을 리턴하든가해서 못만든다고 알려주지않나요?

왜 계속해서 소켓번호를 1024로 넘겨주는 건지...

리턴값이 -1이 되게하든가 다른 방법으로 잘못됐다는 걸 알 수 있는 방법이 있는건가요?

socket에서 그냥 넘어가니까 다음에 오는 connect에서 에러가... 우우웅...

부디 가르침을...

partout의 이미지

간단하게라도 해당하는 부분의 소스를 올려주시는 것이 어떨까요?

어찌나 졸린지..~~

bugiii의 이미지

아래와 같습니다. 어느분이 스캐너 말씀을 하시길래 pth를 사용해서 간단하게 해볼려고 했는데요. pth_connect_ev에서 막긴 했습니다만... 찜찜해서요.
그럼, 부탁드립니다.

#include <pth.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include <iostream>
#include <vector>
#include <deque>

using namespace std;

bool		verbose = false;
char*		ip_str;
in_addr_t	ip;
in_port_t	port_start = 1;
in_port_t	port_end = 1024;
int			port_len = 1024;
int			max_thread = 100;
int			timeout = 10;

deque< in_port_t > port_q;

static void* port_scan_thread( void* arg )
{
	bool run_thread = true;
	
	while( !port_q.empty() && run_thread )
	{
		int s = socket( AF_INET, SOCK_STREAM, 0 );
		if( s < 0 )
			continue;

		in_port_t port = port_q.front();
		port_q.pop_front();

		sockaddr_in addr;
		bzero( &addr, sizeof(addr) );
		addr.sin_family = AF_INET;
		addr.sin_addr.s_addr = ip;
		addr.sin_port = htons( port );

		pth_event_t ev = pth_event( PTH_EVENT_TIME, pth_timeout( timeout, 0 ) );

		if( pth_connect_ev( s, (const sockaddr*)&addr, sizeof(addr), ev ) == 0 )
			cout << port << endl;
		else
		{
			if( verbose )
				cerr << s << " : " << port << " : " << strerror( errno ) << endl;

			if( EBADF == errno /*|| ENOTSOCK == errno*/ )
			{
				port_q.push_front( port );		
				run_thread = false;
			}
		}

		pth_event_free( ev, PTH_FREE_THIS );
		
		close( s );
	}
	
	return( 0 );
}

bool handle_options( int argc, char* argv[] )
{
	while( true )
	{
		int ch = getopt( argc, argv, "vs:e:n:t:" );
		if( -1 == ch )
			break;

		switch( ch )
		{
			case 'v':
				verbose = true;
				break;
			case 's':
			case 'e':
				{
					int port = atoi( optarg );
					if( (port < 1) || (65535 < port) )
						return( false );
					((ch == 's') ? port_start : port_end) = port;
				}
				break;
			case 'n':
				max_thread = atoi( optarg );
				if( 0 == max_thread )
					return( false );
				break;
			case 't':
				timeout = atoi( optarg );
				if( timeout < 1 )
					return( false );
				break;
			case '?':
				return( false );
				break;
			default:
				break;
		}
	}
	argc -= optind;
	argv += optind;

	if( port_end < port_start )
		return( false );

	if( NULL == *argv )
		return( false );

	ip_str = *argv;
	ip = inet_addr( *argv );
	if( 0xFFFFFFFF == ip )
		return( false );

	port_len = port_end - port_start + 1;
	if( port_len < max_thread )
		max_thread = port_len;

	return( true );
}

int main( int argc, char* argv[] )
{
	if( pth_init() == FALSE )
		return( -1 ); 
		
	signal(SIGPIPE, SIG_IGN);

	if( !handle_options( argc, argv ) )
	{
		//usage();
		cerr << "error" << endl;
		return( -1 );
	}

	if( verbose )
	{
		cerr << "ip: " << ip_str << endl;
		cerr << "start port: " << port_start << endl;
		cerr << "end port: " << port_end << endl;
		cerr << "max thread: " << max_thread << endl;
	}

	for( int i = port_start; i <= port_end; ++i )
		port_q.push_back( i );

	typedef vector< pth_t > pth_list;
	pth_list thread_list;

	for( int i = 0; i < max_thread; ++i )
	{
		pth_t new_thread = pth_spawn( NULL, port_scan_thread, NULL );
		if( NULL == new_thread )
			break;
		thread_list.push_back( new_thread );
	}

	for( pth_list::const_iterator i = thread_list.begin(); i != thread_list.end(); ++i )
	{
		if( NULL != *i )
			pth_join( *i, NULL );
	}

	pth_kill();

	return( 0 );
}
mastercho의 이미지

방법이 없다면
accept 할때와 close할때 카운팅을 하도록 하면....

안될까요?

변수 하나 둬서 --;

승자는 자기보다 우월한 사람을 보면 존경심을 갖고 그로부터 배울 점을 찾지만 패자는 자기보다 우월한 사람을 만나면 질투심을 갖고 어디 구멍난 곳이 없는지 찾는다.
- 하비스

bugiii의 이미지

한 프로세스에서 열 수 있는 파일 디스크립터 개수 제한을 알아내고 이미 열려 있는 fd 개수 알아낸 다음에 작업을 하라는 말씀이신가요?
그렇게 해도 되는건가요? (유닉스쪽은 초짜라...)
p.s. accept는 없는데요... -_-;

mastercho의 이미지

bugiii wrote:

리턴값이 -1이 되게하든가 다른 방법으로 잘못됐다는 걸 알 수 있는 방법이 있는건가요?
부디 가르침을...

저도 초짜라 잘은 모르지만요

1024개에서 뭔가 제한을 걸고 싶다면

변수를 하나두고 0으로 초기화 한다음

그 변수가 == 1024 인지 체크 하는겁니다

아니라면
소켓을 생성할때 그 변수값을 += 1 해주는겁니다

만약에 1024라면 원하시던 -1로 리턴할때와 같은 방법으로

처리를 하시면 되고요

그리고 소켓을 close 할때 그 변수값을 -= 1 해주면

원하시는 결과를 얻을수 있지 않을까 싶습니다

그럼

승자는 자기보다 우월한 사람을 보면 존경심을 갖고 그로부터 배울 점을 찾지만 패자는 자기보다 우월한 사람을 만나면 질투심을 갖고 어디 구멍난 곳이 없는지 찾는다.
- 하비스

bugiii의 이미지

네. 개수를 안다면 그렇게 해도 괜찮겠습니다만,
제가 원하는 것은 개수 제한이 있다면 socket()이 '더 못만들겠다'고 -1을 리턴해야 옳지않은가 해서요.
os별로 제한은 다 틀릴테고 설정마다 틀릴테고 알아내는 방법도 틀릴테고...
그러니, 못만드는 상황을 제대로 알려줘야 한다 (알고싶다) 는 것입니다.
그럼, 총총...

mastercho의 이미지

man socket하면 각[현재 사용하고 있는]OS별로 잘 나올텐데요 --;

리눅스는 -1를 리턴한다고 나오는데 BSD는 다른거 보네요

승자는 자기보다 우월한 사람을 보면 존경심을 갖고 그로부터 배울 점을 찾지만 패자는 자기보다 우월한 사람을 만나면 질투심을 갖고 어디 구멍난 곳이 없는지 찾는다.
- 하비스

bugiii의 이미지

프비에서도 마찬가지로 -1 돌려준다고 나오거든요...

http://www.freebsd.org/cgi/man.cgi?query=socket&apropos=0&sektion=0&manpath=FreeBSD+4.8-RELEASE&format=html

냠...

asteroid의 이미지

socket의 리턴값이 0이상의 값이라는 것은,

소켓이 제대로 만들어 졌다는 것을 의미하지 않나요?

1024개 이상의 FD를 생성할 수 있는 설정이 된 프리비인것 같습니다만.

pstat -T 로 maxfiles값을 확인해보세요.

bugiii의 이미지

지금 제 상황은 다음과 같습니다. sysctl 로 kern.maxfiles 를 변경하기도 해보았습니다.

#pstat -T
139/16000 files
0M/1008M swap space

#limit descriptors
descriptors 7351

입니다.

쉘에서 limit descriptors 로 1024보다 작거나 같으면 원하는 동작을 합니다.
하지만 크면... 여전하군요.

제가 뭘 잘못 알고 있는 걸까요? T.T

댓글 달기

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