open_clientfd 和 open_listenfd函数

转载出处http://blog.chinaunix.net/uid-12076195-id-229341.html

open_clientfd函数


我们发现将socket和connect封装成一个叫做open_clientfd的函数是很方便的,客户端可以用它来和服务器建立连接。

int open_clientfd(char * hostname, int port);
         返回:成功则为描述符,若Unix出错则为-1,若DNS出错则为-2。
---------------------------------------------------------------------
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>

typedef struct sockaddr SA;

int
open_clientfd(char * hostname, int port)

{
    int clientfd;
    struct hostent *hp;
    struct sockaddr_in serveraddr;

    /* Create a socket discriptor */
    if ((clientfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        fprintf(stderr, "socket error: %s\n", (char *)strerror(errno));
        return -1;
    }

    /* Fill in the server’s IP address and port */
    if ((hp = gethostbyname(hostname)) == NULL) {
        fprintf(stderr, "gethostbyname error: %s\n",  (char *) strerror(errno));
        close(clientfd);
        return -2;
    }
    bzero((char *)&serveraddr, sizeof(serveraddr));
    serveraddr.sin_family = AF_INET;
    bcopy((char *)hp->h_addr,
            (char *)&serveraddr.sin_addr.s_addr, hp->h_length);
    serveraddr.sin_port = htons((unsigned short)port);

    /* Establish a connection with the server */
    if (connect(clientfd, (SA *)&serveraddr, sizeof(serveraddr)) < 0) {
        fprintf(stderr, "connect error: %s\n", 
(char *) strerror(errno));
        close(clientfd);
        return -1;
    }

    return clientfd;

}

=================================================================================
open_listenfd函数

我们发现将socket、bind和listen封装成一个叫做open_listenfd的函数是很方便的,服务器可以用它来创建一个监听描述符。

int open_listenfd(int port);
         返回:成功则为描述符,若Unix出错则为-1。
---------------------------------------------------------------------
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>

#define LISTENQ 1024
typedef struct sockaddr SA;

int
open_listenfd(int port)

{
    int listenfd, optval = 1;
    struct sockaddr_in serveraddr;

    /* Create a socket discriptor */
    if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        fprintf(stderr, "socket error: %s\n", 
(char *) strerror(errno));
        return -1;
    }

    /* Eliminates "Addrss already in use" error from bind */
    if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR,
            (const void *)&optval, sizeof(int)) < 0) {
        fprintf(stderr, "setsockopt error: %s\n", 
(char *) strerror(errno));
        goto err_out;
    }

    /* Listenfd will be an endpoint for all requests to port
       on any IP address for this host */
    bzero((char *)&serveraddr, sizeof(serveraddr));
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
    serveraddr.sin_port = htons((unsigned short)port);

    if (bind(listenfd, (SA *)&serveraddr, sizeof(serveraddr)) < 0) {
        fprintf(stderr, "bind error: %s\n", 
(char *) strerror(errno));
        goto err_out;
    }

    /* Make it a listening socket ready to accept connection request */
    if (listen(listenfd, LISTENQ) < 0) {
        fprintf(stderr, "listen error: %s\n", 
(char *) strerror(errno));
        goto err_out;
    }
    return listenfd;

err_out:
    close(listenfd);
    return -1;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值