2015년 5월 3일 일요일

setsockopt 의 SO_SNDBUF 설정 후, 설정 값이 2 개가 되는 현상.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <errno.h>
#include <string.h>
 
 
void error_handle( char * msg);
 
int main(int argc, char * argv[] )
{
    int sock_tcp;
    int sock_udp;
 
    int option;
    socklen_t length; // sys/types.h
 
    sock_tcp = socket( PF_INET, SOCK_STREAM, 0 );
 
    if( sock_tcp == -1 )
        error_handle( "socket error()" );
 
    sock_udp = socket( PF_INET, SOCK_DGRAM, 0 );
 
    if( sock_udp == -1 )
        error_handle( "scoket error()" );
 
 
 
 
    length = sizeof( option );
    if( getsockopt( sock_tcp, SOL_SOCKET, SO_SNDBUF, (void*) &option, &length ) == -1 )
        error_handle( "getsockopt() error" );
 
    printf( "tcp send    buffer size : %d\n", option );
 
    length = sizeof( option );
    if( getsockopt( sock_tcp, SOL_SOCKET, SO_RCVBUF, (void*) &option, &length ) == -1 )
        error_handle( "getsockopt() error" );
 
    printf( "tcp receive buffer size : %d\n", option );
 
 
    option = 1024 * 10;
    if( setsockopt( sock_tcp, SOL_SOCKET, SO_SNDBUF, (void*) &option, sizeof( option ) ) == -1 )
        error_handle( "setsockopt() error" );
 
    length = sizeof( option );
    option = 1024 * 20;
    if( setsockopt( sock_tcp, SOL_SOCKET, SO_RCVBUF, (void*) &option, sizeof( option ) ) == -1 )
        error_handle( "setsockopt() error" );
 
 
    length = sizeof( option );
    if( getsockopt( sock_tcp, SOL_SOCKET, SO_SNDBUF, (void*) &option, &length ) == -1 )
        error_handle( "getsockopt() error" );
 
    printf( "tcp send    buffer size : %d\n", option );
 
    length = sizeof( option );
    if( getsockopt( sock_tcp, SOL_SOCKET, SO_RCVBUF, (void*) &option, &length ) == -1 )
        error_handle( "getsockopt() error" );
 
    printf( "tcp receive buffer size : %d\n", option );
 
 
    /*
    length = sizeof( option );
    if( getsockopt( sock_udp, SOL_SOCKET, SO_SNDBUF, (void*) &option, &length ) == -1 )
        error_handle( "getsockopt() error" );
    printf( "udp send    buffer size : %d\n", option );
    length = sizeof( option );
    if( getsockopt( sock_udp, SOL_SOCKET, SO_RCVBUF, (void*) &option, &length ) == -1 )
        error_handle( "getsockopt() error" );
    printf( "udp receive buffer size : %d\n", option );
    */
 
    close (sock_tcp);
    close (sock_udp);
 
    return 0;
}
 
 
void error_handle( char * msg )
{
    fprintf( stderr, "%s\n", msg );
    fprintf( stderr, "errno number : %d\n", errno );
    fprintf( stderr, "errno message: %s\n", strerror( errno ) );
    exit(1);
}
 
cs



위 코드의 결과.

tcp send    buffer size : 16384
tcp receive buffer size : 87380
tcp send    buffer size : 20480
tcp receive buffer size : 40960


실제
setsockopt 의 변수로, 10240 을 주면 그의 2 배인 20480,
setsockopt 의 변수로, 20480 을 주면 그의 2 배인 40960
이 나온다.

왜 그런지 확인해 보려면,

man 7 socket
명령어를 linux 에서 실행시켜 보면,

아래와 같은 안내를 볼 수 있다.

       SO_SNDBUF
              Sets  or gets the maximum socket send buffer in bytes.  The kernel doubles this value (to allow space for
              bookkeeping overhead) when it is set using setsockopt(2), and this doubled value is returned by  getsock‐
              opt(2).   The  default  value  is set by the /proc/sys/net/core/wmem_default file and the maximum allowed
              value is set by the /proc/sys/net/core/wmem_max file.  The minimum (doubled) value  for  this  option  is
              2048.



UDP와 TCP 소켓의 SND/RCV 버퍼 크기 보기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <errno.h>
#include <string.h>
void error_handle( char * msg);
int main(int argc, char * argv[] )
{
    int sock_tcp;
    int sock_udp;
    int option;
    socklen_t length; // sys/types.h
    sock_tcp = socket( PF_INET, SOCK_STREAM, 0 );
    if( sock_tcp == -1 )
        error_handle( "socket error()" );
    sock_udp = socket( PF_INET, SOCK_DGRAM, 0 );
    if( sock_udp == -1 )
        error_handle( "scoket error()" );
    length = sizeof( option );
    if( getsockopt( sock_tcp, SOL_SOCKET, SO_SNDBUF, (void*) &option, &length ) == -1 )
        error_handle( "getsockopt() error" );
    printf( "tcp send    buffer size : %d\n", option );
    length = sizeof( option );
    if( getsockopt( sock_tcp, SOL_SOCKET, SO_RCVBUF, (void*) &option, &length ) == -1 )
        error_handle( "getsockopt() error" );
    printf( "tcp receive buffer size : %d\n", option );
    length = sizeof( option );
    if( getsockopt( sock_udp, SOL_SOCKET, SO_SNDBUF, (void*) &option, &length ) == -1 )
        error_handle( "getsockopt() error" );
    printf( "udp send    buffer size : %d\n", option );
    length = sizeof( option );
    if( getsockopt( sock_udp, SOL_SOCKET, SO_RCVBUF, (void*) &option, &length ) == -1 )
        error_handle( "getsockopt() error" );
    printf( "udp receive buffer size : %d\n", option );
    close (sock_tcp);
    close (sock_udp);
    return 0;
}
void error_handle( char * msg )
{
    fprintf( stderr, "%s\n", msg );
    fprintf( stderr, "errno number : %d\n", errno );
    fprintf( stderr, "errno message: %s\n", strerror( errno ) );
    exit(1);
}


위와 같은 코드를 사용해서,
UDP와 TCP 소켓의 send buffer 와 receive buffer 크기를 살펴보니,
기본적으로 다르게 설정되어 있음을 알았다.


이를 실행하면,

tcp send buffer size : 16384
tcp receive buffer size : 87380
udp send buffer size : 112640
udp receive buffer size : 112640
이 나왔다.

Linux 에서 기본 설정하는 TCP SND/RCV 버퍼 크기는
sysctl -n net.ipv4.tcp_wmem ( SND 크기 )
sysctl -n net.ipv4.tcp_rmem ( RCV 크기 )
명령어로 확인할 수 있다.


UDP 의 경우 아래로 확인하면 될 것 같다.
sysctl -n net.core.wmem_default sysctl -n net.core.rmem_default


https://wwwx.cs.unc.edu/~sparkst/howto/network_tuning.php

cs

2015년 1월 31일 토요일

영어 행성 이름 순서 외우는 방법.

how to memorize the order of planets in solar system.

My very educated mother just served us nine pies.
아주 교양있는 우리 어머니께서 방금 우리에게 파이 아홉 개를 주셨다.

Mercury
Venus
Earch
Mars
Jupiter
Saturn
Uranus
Neptune
Pluto

출처
행성이야기 (The Planets)
작가 : 데이바 소벨 (Dava Sobel )

2015년 1월 22일 목요일

ddd 를 이용하여 구조체 내에 padding 된 byte 의 쓰레기값 관찰하기.

#include

typedef struct _a
{
char a;
int  i;
}PAD;

typedef struct __attribute__((packed)) _b
{
char a;
int  i;
}PACK;

int main(int argc, char * argv[] )
{
PAD  pad = { 'a', 10 };
PACK pack= { 'b', 20 };

printf( "PAD  char  : %c\n", pad.a );
printf( "PACK char  : %c\n", pack.a );


printf( "size PAD  : %d\n", sizeof(PAD ) );
printf( "size PACK : %d\n", sizeof(PACK) );

return 0;
}


위 코드를 이용하여 ddd 를 사용해보자.


(gdb) print pad.a
$9 = 97 'a'

(gdb) print pad
$10 = {a = 97 'a', i = 10}

pad 의 주소를 출력
(gdb) print &pad
$13 = (PAD *) 0xbffff240


pad.a 의 주소를 출력(값도 같이 나온다.)
(gdb) print &pad.a
$14 = 0xbffff240 "a\324\025"    

a 는 초기화된 값인데, 그 뒤의 값은 왜 저렇게 나오는지 모르겠다.


pad.a 의 주소를 이용하여 word(32bit 컴에서 4 byte) 를 출력
(gdb) x /wx &pad.a
0xbffff240: 0x0015d461

pad.a 의 주소를 이용하여 1 byte 를 출력
(gdb) x /bx &pad.a
0xbffff240: 0x61

( pad.a + 1 ) 주소를 이용하여 1 byte 를 출력
(gdb) x /bx &pad.a + 1
0xbffff241: 0xd4

( pad.a + 2 ) 주소를 이용하여 1 byte 를 출력
(gdb) x /bx &pad.a + 2
0xbffff242: 0x15

( pad.a + 3 ) 주소를 이용하여 1 byte 를 출력
(gdb) x /bx &pad.a + 3
0xbffff243: 0x00





2015년 1월 12일 월요일

ddd 에서 인자주기

http://www.delorie.com/gnu/docs/gdb/gdb_19.html

set args
Specify the arguments to be used the next time your program is run. If set args has no arguments, run executes your program with no arguments. Once you have run your program with arguments, using set args before the next run is the only way to run it again without arguments.
show args
Show the arguments to give your program when it is started.

또는 

After you invoke ddd, goto Program->Run and then provide your arguments.

2014년 12월 31일 수요일

Activeperl 에서 perk/Tk 를 이용하기.


https://code.activestate.com/ppm/Tk/
에서 정보를 참조함.

Windows 에서 perl 5.16 버전의 경우, Tk 를 지원한다고 적혀 있음.

그리고
Windows 의 command 창에서
ppm install Tk 
를 실행시킴.



위 그림과 같이 설치가 완료됨.

그리고 같단한 Tk 예제를 실행시키니 정상적으로 실행됨을 확인했음.

2014년 12월 6일 토요일

Linux File Redirection




http://www.tldp.org/LDP/abs/html/io-redirection.html

https://www.digitalocean.com/community/tutorials/an-introduction-to-linux-i-o-redirection

파일 리다이렉션할 때 항상 헛갈리는 부분이 있었는데 검색을 통해 확실히 정리함.
( 위 사이트에 정리가 잘 되어 있었음. )

command &> filename
    이건 stdout 과 stderr 을 모두 "filename" 이라는 파일로 redirection 하라는 의미.

command 2>&1
     이건 file descriptor 2 번( stderr )을  file descriptor 1 번(stdout) 로 redirection 하라는 의미.
  이것의 일반적인 표현은  command M>&N  즉 M 파일 서술자를  N 파일 서술자로 redirection 하라는 의미.



팔로어