connect(2)

#include <sys/socket.h>

int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

서버의 주소(addr)로 접속하여 connection을 유지합니다. connect(2) 함수는 socket(2)의 type 설정시 SOCK_STREAM, SOCK_SEQPACKET 등으로 설정된 connection-base socket의 경우에만 가능합니다. 두번째 파라미터인 struct sockaddr는 Address Family에 따라서 다른 구조체를 갖습니다. (참조: struct sockaddr - Address Family에 따른 구조체)

 

 

파라미터

sockfd
    - socket(2)의 두번째 parameter인 type이 SOCK_STREAM, SOCK_SEQPACKET으로 생성한 socket descriptor.
addr
    - socket에 설정할 주소 정보에 대한 struct입니다.

 struct sockaddr는 socket을 지원하는 Protocol의 기본 골격에 대한 sturct 이며,
 AF_* (Address Family)에 따라서 struct를 다르게 정의하여 사용합니다.

 struct sockaddr {
     sa_family_t sa_family;
     char        sa_data[14];
 };
 로 sa_family에 AF_*값을 설정하고 AF_*값에 따라서 sa_data의 구조가 다릅니다.
 따라서 AF_*값에 따라서 구조체를 재정의하여 사용하며, 
 Address Family에 따라서 char sa_data[14]; 즉, 14 바이트보다 큰 경우가 있으므로
 사실상 struct sockaddr은 의미가 없는 구조체입니다.
addrlen
    - addr 구조체의 크기를 저장한 변수입니다. (AF_* 상수에 따라 크기가 다름)

 

RETURN

-1이 아님
    - 정상적으로 connection되었습니다.

-1
    - 오류가 발생하였으며, 상세한 오류는 errno에 저장됩니다.
  EACCES : AF_UNIX, AF_LOCAL에서 directory 또는 file에 대한 권한이 없음.
  EACCES, EPERM : socket에 broadcasting flag없이 broadcasting으로 접속시도함.
  EADDRINUSE : local 주소를 이미 사용중임.
  EAFNOSUPPORT : struct sockaddr의 sa_family field의 값을 잘못 설정함.
  EAGAIN : struct sockaddr의 sa_family field의 값이 AF_INET일 때, 사용할 local port가 없는 경우
  EALREADY : socket이 nonblocking으로 설정되고 이미 connection 시도를 한 경우
  EBADF : sockfd가 유효하지 않은 경우
  ECONNREFUSED : 서버 소켓이 listen 상태가 아니거나 방화벽으로 막혔을 때.
  EFAULT : The socket structure address is outside the user's address space.
  EINPROGRESS : socket이 nonblocking이고 바로 접속할 수 없을 때. 
  EINTR : signal이 발생하여 catch된 경우 (재시도 필요)
  EISCONN : 이미 connect됨.
  ENETUNREACH : Network이 도달할 수 없음
  ENOTSOCK : socket descriptor가 아님.
  ETIMEDOUT : 접속시 timeout 발생함.

 


활용 예제

 

Sample 1. TCP/IP connect by domain name

#include <stdio.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>

#define SERVER_PORT   6905
#define SERVER_NAME   "job.mydomain.com"

......

struct hostent *he;
struct sockaddr_in server_addr;
int  sock;

......

if((he = gethostbyname(SERVER_NAME)) == NULL) {
    fprintf(stderr, "%s는 등록되지 않은 서버명입니다.\n", SERVER_NAME);
    return -1;
}

memset(&server_addr, 0x00, sizeof(struct sockaddr_in));
server_addr.sin_family = AF_INET;
memcpy(&server_addr.sin_addr.s_addr, he->h_addr, he->h_length);
server_addr.sin_port   = htons(SERVER_PORT);

if((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
    fprintf(stderr, "Socket 생성 오류: %s\n", strerror(errno));
    return -1;
}

if(connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr_in)) == -1) {
    fprintf(stderr, "Connection Error: %s\n", strerror(errno));
    close(sock);
    return -1;
}

......

 

Sample 2. TCP/IP connect by IP address

#include <stdio.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>

#define SERVER_NAME   "127.0.0.1"
#define SERVER_PORT   6905

......

struct sockaddr_in server_addr;
int  sock;

......

memset(&server_addr, 0x00, sizeof(struct sockaddr_in));
server_addr.sin_family      = AF_INET;
server_addr.sin_addr.s_addr = inet_addr(SERVER_NAME);
server_addr.sin_port        = htons(SERVER_PORT);

if((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
    fprintf(stderr, "Socket 생성 오류: %s\n", strerror(errno));
    return -1;
}

if(connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr_in)) == -1) {
    fprintf(stderr, "Connection Error: %s\n", strerror(errno));
    close(sock);
    return -1;
}

......

 


see also : Socket 통신과 Socket 응용

 

 

 

 

블로그 이미지

자연&사람

행복한 개발자 programmer since 1995.

댓글을 달아 주세요