open_clientfd 和 open_listenfd函数

来源:互联网 发布:led显示屏网络推广 编辑:程序博客网 时间:2024/06/05 22:56

转载出处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;
}
0 0
原创粉丝点击