#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    struct sockaddr_in local;
    struct sockaddr_in client;
    int *csize;
    int s;    int s1;    int rc; char buf[1];
    local.sin_family = AF_INET;
    local.sin_port = htons(5300);
    local.sin_addr.s_addr = htonl(INADDR_ANY);
   
    char getTime[255];

    //added by Justin
   
    printf("A server has been started, the port number is reserved as 5300\n\n");


    s = socket(PF_INET, SOCK_STREAM, 0);
    if(s<0){
        perror("socket call failed");
        exit(1);
    }

    rc = bind(s, (struct sockaddr *)&local, sizeof(local));
    if(rc<0){
        perror("bind call failure");
        exit(1);
    }


    printf("A server is waintg for a client request\n\n");

    rc = listen(s,5);
    if(rc){
        perror("listen call failed");
        exit(1);
    }



    csize = sizeof(client);        // this is used to get a ip address using accept()

    s1= accept(s,(struct sockaddr*)&client ,&csize);    // we need to know the ip address of a client
    // to get client address. then we have to send this client
    // address to the client.

    printf("Conntection established!\n\n");

    if(s1<0){
        perror("accept call failed");
        exit(1);
    }

    rc = recv(s1,getTime ,sizeof(getTime), 0);    // rc return the size of the data

    if(rc<=0){
        perror("recv call failed");
        exit(1);
    }

    printf("\nCurrent time from client : %s \n", getTime);        //print current Time

    printf("\n\nA server will send a client's IP address \n");

    rc = send(s1, &client , sizeof(client), 0);        // send a structure of sockaddr_in to the client
    if(rc <= 0)                        // if it failes
    {
        perror("send call failed");
        exit(0);
    }
}


accept should have the sockaddr struct as long as we want to know about client's address information
In this example, client.sin_addr has a IP address of a client and client.sin_port has a port #


'Programming > Network Programming' 카테고리의 다른 글

.. no regret..  (0) 2011.10.26
The example of one server that sends a client ID  (0) 2011.10.15
Reference for unix socket api  (0) 2011.09.29
TCP/IP  (0) 2011.09.21
The concept of TCP/IP part 1.  (2) 2011.09.07
Posted by 박세범

in order to get the mode of a file, we need to get the information of Inode struct

fortunately, there is a api stat() or fstat()

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>

int main(int argc, char *argv[])
{
       int fd;
       struct stat info;                  // in order to get the status of a file
       fd = open(argv[1],O_REWR);
       fstat(fd, &info);                   //fstat(int fileDescriptor, struct stat* info)
       printf(fd, (unsigned long)info.st_mode);
        return 0;
}

st_mode is one structure in struct stat info. it has a mode of a file(permission)
so if we use this we can copy a file whose mode is exactly same as the file we want to copy from

Posted by 박세범


Prototype

Return value

Parameter

The role of function

int socket(int domain,
int type int protocol)

양의 정수 : socket descriptor
-1 :
소켓 생성 실패

domain : PF_INET: protocol type
                 PF_INET6 : IPv6
                  PF_UNIX : UNIX
방식의 프로토콜
type : SOCK_STREAM : TCP
           SOCK_DGRAM : UDP

           SOCK_RAW : raw(ICMP)
protocol : IPPORTO_TCP
                  IPPROTO_UDP
                  0(for TCP, UDP)

새로운 소켓을 만들 쓰이며, 반드시 return 값을 가지고 있어야 한다. Return 값은 추후 소켓을 구별 하는대 쓰인다.

함수는 bind() or connect() 함께 쓰인다.

int close(int socket)

0 : 소켓 종료가 정상적으로 이뤄짐
-1 :
소켓 종료를 실패함

socket : socket()에서 만들어진
               socket desrtiptor

소켓을 종료할 쓰이며, 상당시간 동안
time_wait
상태를 유지함에 유의하자.

int bind(int socket,
const struct sockaddr *localaddr
int addrlen)

0 : bind 성공했을 경우
-1 : bind
실패했을 경우

socket : socket() return
localaddr :
서버의 주소를 가진 구조체, 대게 sockaddr_in
addrlen :
구조체의 크기

서버 프로그램이
sock
에게 port(이름) 할당(등록) 한다.

int listen(int socket, int queuesize)

0 : 성공했을 경우
-1 :
실패 했을 경우

socket : socket() 의핸 return socket descriptor
queuesize : queue
최대크기
                    
최대는 5이다

생성된 소켓이 client 연결을 기다리는 함수
queue
최대 길이를 설정한다.

int accept(int socket,
struct sockaddr *caddress
int *caddresslen)

-1 : 실패했을 경우
양의정수 : socket I/O 위한
non-negative descriptor
반환

socket :  socket() return
caddress : sockaddress_in
구조체 포인터,
                   client address
저장된다.
caddresslen : sockaddress_in
구조체의 길이의 포인터

Queue 들어있는 처음 연결을 추출하는 함수, 만약 queue 비어있다면 blocking 된다.
client
로부터 연결요청을 받아 통신을 위한
새로운 소켓을 생성한 연결한다.

int connect(int socket,
const struct sockaddr *serveraddress
int serveraddresslen)

0 : 성공했을 경우
0
아닌 정수값 : 실패할 경우

Socket : socket() return
serveraddress :
서버주소를 가지고 있는
                           
구조체의 포인터
serveraddresslen :
서버주소를 가지고 있는
                                 
구조체의 길이

Socket 다른 socket 연결한다.
서버와의 통신을 위해 통신 연결을 요청하며 주로
client
쪽에서 행에진다. 3way-handshaking
이때 발생한다.

int send(int socket, const char* data
int length, int flags)

-1 : 실패했을 경우
the # of byte :
성공했을 경우

Socket() : accept()에서 만들어진 descriptor
data : 
보내고 싶은 data
length : data
길이(byte)
flags :
대게 0으로 설정

상대방 프로그램에게 데이터를 송신한다.
만약 성공했을 경우 data TCP buffer 전송되었다는 것을 의미하며
전송 버퍼에 저장된 데이터는 ACK메세지를 수신하면서 삭제된다.


int recv(int socket, char*data,
int length, int flags)

Buffer 읽힌 byte
-1 :
에러가 생길 경우
0 :
접속종료를 알림

Socket : accept()에서 만들어진 descriptor
data :
수신받는 data
length : data
길이
flags :
대게 0으로 설정

Protocol(i.e : TCP) buffer 읽는 byte 읽는 함수이다.
stream
형식의 byte 읽는 것에 유의해야 하며 첫번째 parameter socket file descriptor(accept() 반환값)
임에 유의해야 한다.

int sendto(int socket, char* data,

Lint length, int flags,
struct sockaddr *destaddress,
int addresslen)

the # of byte : 성공했을 경우
-1 :
실패했을 경우

socket : accept() return
data :
원하는 data

length : data 길이
flags :
대게 0으로 설정
destaddress :
목적지의 address 가지고
                        
있는 구조체의 포인터
addresslen : destaddress
크기

Datagram 스타일의 전송방식으로써(datagram socket 다른 remote host 보지 못한다) 패킷을 전송하고
수신할 연결되지 않은 소켓을 통해 송신한다.
따라서 패킷을 보내기 destaddress 구조체를
이용하여 전송한다.

int recvform(int socket, char*data, lint length, int flags,
struct sockaddr *srcaddress,
int *addresslen)

Buffer 읽힌 byte
-1 :
에러가 생길 경우
0 :
접속종료를 알림

socket : accept() return
data :
원하는 data

length : data 길이
flags :
대게 0으로 설정
destaddress :
수신자의 address 가지고 있는
                         
구조체의 포인터
addresslen : destaddress
크기

Sendto() 형식과 같으며, 단지 receive() 하는
역할만이 다르다.

int setsockopt(int socket, int level,
int opt, const char* optval,
int optlen)

0 : 성공했을 경우
-1 :
실패했을 경우

Socket : socket() 반환값
level : SOL_SOCKET, IPPROTO_IP, IPPROTO_TCP
optval :
level == SOL_SOCKET ?
              SO_REUSEADDR  - IP addr/port
재사용
               SO_KEEPALIVE –
주기적 연결상태 확인
               SO_BROADCAST -
방송 전송 허용
               SO_LINGER - Closesocket()
처리 방식
               SO_SNDBUF -
송수신 버퍼 크기 설정

               SO_SNDTIME - 송수신 함수 타임아웃
level == IPPROTO_IP ?
               IP_TTL – TTL
설정

            IP_HDRINCL – 헤더 포함 전송
            IP_MULTUCAST_IF :
다중전송

 

생성된 소켓의 옵션을 설정하는 함수이다.

Parameter level opt 따라 결과 값이 바뀌게 된다.



int getsockopt(int socket, int level,
int opt, const char* optval,
int optlen)

0 : 성공했을 경우

-1: 실패했을 경우

setsockopt() 함수와 기본적으로 옵션이 같으며
opt
level 지정하면 원하는optval
값을 얻을 있다

소켓옵션을 확인하기 위한 함수이며, optval 값을 읽어드리며, 포인터로 지정한 변수에 값이 읽히게 된다.

struct hostent *gethostbyname(const char *name)

Struct hostent : 성공 했을 경우
서버에 관한 정보들이 구조체에 들어가게 된다.
NULL :
실패할 경우.

name : domain명을 적으면 된다.
             i.e) www.naver.com

도메인의 이름을 (ie. naver.com) 네트워크 바이트로
정렬된 2진수 IP주소로 변환한다. IPv6와의 호환성
때문에 최근에는 getaddrinfo() 혹은 getnameinfo() 쓴다

 

struct hostent *gethostbyaddr(const char *addr, int len, int type)

 

Struct hostent : 성공 했을 경우
서버에 관한 정보들이 구조체에 들어가게 된다.
NULL :
실패할 경우.

addr : IP 주소
len : IP
주소의 길이
type : IP
주소 type

이진수 IP주소를 도메인 이름으로 바꿔준다. 기본적인 개념은 gethostbyname()함수와 같다.


 

char *inet_ntoa(struct in_addr in);

int inet_aton(const char *cp,
struct in_addr *inp);

inet_ntoa()
     ip
주소 형태의 string 반환
 
 inet_aton()
     Non-zero :
주소가 valid 경우
     0 :
주소가 틀렸을 경우      

in : struct in_addr (ip주소를 담고 있는 구조체)
cp :
문자열 형태의 address
inp :
문자열 형태의 address IP형태로 변환할
        
저장될 struct in_addr 구조체

Number -> address, address -> number
변환이 필요할 쓰이며, 현재는 IPv6와의 호환성 때문에 inet_ntop() inet_pton()으로 대체되었다.

 

in_addr_t inet_addr(const char *cp);

 

주소 정보를 가지고 있는
in_addr_t
구조체를 반환한다.

cp : address 문자열

기본적으로 inet_aton() 함수와 같으며, 매우 오래된 method 쓰이지 않는다.

struct servent *getservbyname(                                                const char *name,                                            const char *proto)

 

servent  구조체가 반환되며, 만약 proto 값이 NULL 경우 protocol match되는 servent 구조체가 반환된다.

0 : 실패할경우 0 반환한다

name : servce 이름을 쓴다(program)
proto :
프로토콜 type 쓴다(TCP or UDP)

Parameter 주어진 이름과 프로토콜이 match되는
service
정보를 찾아서 정보를 가진servent 구조체로
반환하는 함수이다.

 

struct servent *getservbyport(int port, const char *proto);

 

servent  구조체가 반환되며, 만약 proto 값이 NULL 경우 protocol match되는 servent 구조체가 반환된다.

0 : 실패할경우 0 반환한다

port : 원하는 port # 쓴다.
proto : protocol type
쓴다(TCP or UDP)

 

기본적인 parameter getservbyname() 같다.

Paramter 주어진 port proto 매치되는 service정보를 찾아서 정보를 servent 구조체로 반환하는 함수이다.

uint32_t htonl(uint32_t hostlong);

uint16_t htons(uint16_t hostshort);

uint32_t ntohl(uint32_t netlong);

uint16_t ntohs(uint16_t netshort);

 

함수는 변환된 값을 반환한다.
uint32
4byte 의미하며
unint16
2byte 의미한다.

hostlong :  host long type 데이터
hostshort : host
short type 데이터
netlong : network
long type 데이터
netshort : network
short type 데이터

h : host 의미한다

to : converting 의미한다
n : network
의미한다
l,s :
데이터형을 의미한다
        (long or short)

host byte order로부터 network byte order

multi-byte integer type형식으로 변환한다.

(역도 성립한다, vice versa)

 

함수는 hardware 호환성 때문에 만들어 졌는데, 시스템 마다 각기 다른식으로 byte order 저장하기 때문에 port # 숫자를 네트워크로 전송 했을 경우 함수들을 써야한다.




struct for network-programming(네트워크 프로그래밍을 위한 구조체)

 

1.        struct sockaddr
{
    u_short sa_family;    /* address family */
    char sa_data[14];     /*
주소(IP 주소포트 번호) */
};

 

2.        struct in_addr            /* sockaddr_in 안에 정의되어 있음에 유의하자 */
{
    u_long s_addr;    /* 32
비트의 IP 주소를 저장할 구조체 */
}

 

3.        struct sockaddr_in
{
    short sin_family;            /*
주소 체계 */
    u_short sin_port;           /* 16
비트 포트 번호 */
    struct in_addr sin_addr; /* 32
비트 IP 주소 */
    char sin_zero[8];           /*
전체 크기를 16바이트로 맞추기 위한 dummy */
}


 

 

4.        struct hostent

{

    char *h_name            /*   host 이름 */

    char **h_aliases            /*  aliases(별명?) list , 마지막 요소는 항상 NULL이다 */

    int h_addrtype            /* address 형식 AF_INET 인터넷 주소 체계이다 */

    int length                    /* address 길이, byte단위 이다 */

    char **h_addr_list             /* IP주소의 list들이 있으며, struct in_addr* 가리키는 pointer이다.

}      

 

5.        struct servent
{

        char    *s_name;        /* 공식적인 service 이름*/

        char    **s_aliases;    /* alias(별명?) list */

        int     s_port;         /* port 번호 */

        char    *s_proto;       /* 사용하고 있는protocol  */
}


'Programming > Network Programming' 카테고리의 다른 글

.. no regret..  (0) 2011.10.26
The example of one server that sends a client ID  (0) 2011.10.15
get client IPadrress in server side  (0) 2011.10.10
TCP/IP  (0) 2011.09.21
The concept of TCP/IP part 1.  (2) 2011.09.07
Posted by 박세범