linux网络编程库函数封装

linux网络编程库函数封装

h文件

#ifndef INTERNET_H_
#define INTERNET_H_


#ifdef __cplusplus
extern "C" {
#endif

#include <stdio.h>
#include <ctype.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/epoll.h>


#define IPV4     AF_INET
#define IPV6     AF_INET6


#define TCP     SOCK_STREAM
#define UDP     SOCK_DGRAM

#define PORT        8081
#define LISTEN_NUM  128

#define NET_LOG(format, ...)    printf(format, ##__VA_ARGS__)


typedef struct sockaddr_in      SOCKETADDR_IN;
typedef struct sockaddr         SOCKETADDR;
typedef struct epoll_event      EPOLL_DEF;


int socket_t(int domain, int type);

void bind_t(int server_fd,int type,int port);

void listen_t(int server_fd);

int accept_t(int server_fd);

int socket_init(int domain, int type);

int epoll_init(struct epoll_event *epoll_def_init,int server_fd);

void epoll_add(int epfd,int fd,EPOLL_DEF *epoll_def);

void epoll_delete(int epfd,EPOLL_DEF *epoll_def,int index);

void epoll_accpet(int server_fd,EPOLL_DEF *epoll_def,int epfd);
#ifdef __cplusplus
}
#endif

#endif

c文件

#include "internet.h"


/**
 * fd :
 * bind(lfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));//给服务器socket绑定地址结构(IP+port)
*/
void bind_t(int server_fd,int type,int port){
    int opt = 1;

    SOCKETADDR_IN serv_addr = {  // 定义服务器地址结构 和 客户端地址结构
        .sin_addr.s_addr =  htonl(INADDR_ANY),
        .sin_family = type,
        .sin_port = htons(port)
    };  

    if(type == IPV4){
        NET_LOG("fd = %d type = IPV4 port = %d  ip = %d\r\n",server_fd,port,htonl(INADDR_ANY));
    }else if(type == IPV6){
        NET_LOG("fd = %dtype = IPV6 port = %d  ip = %d\r\n",server_fd,port,htonl(INADDR_ANY));
    }

    //端口复用
    setsockopt(server_fd,SOL_SOCKET,SO_REUSEADDR,(void *)&opt,sizeof(opt));

    if(bind(server_fd, (SOCKETADDR *)&serv_addr, sizeof(serv_addr)) == -1){//给服务器socket绑定地址结构(IP+port)
        perror("bind error\r\n");
        exit(1);
    }
}

/**
 * domain ---> IPv6或者IPv4
 * type   ---> UDP或者TCP
 * return ---> socket创建的文件描述符
 * fd = socket(AF_INET, SOCK_STREAM, 0);		//创建一个 socket
*/
int socket_t(int domain, int type){
    int server_fd;
    if((server_fd = socket(domain, type, 0)) == -1){
        perror("socket error\r\n");
        exit(1);
        return -1;
    }else{
        if(type == TCP){
            NET_LOG("fd = %d TCP socket create success\r\n",server_fd);
        }else if(type == UDP){
            NET_LOG("fd = %d UDP socket create success\r\n",server_fd);
        }
        return server_fd;
    }
}

/**
 * server_fd    文件描述符
*/
void listen_t(int server_fd){
    if(listen(server_fd,LISTEN_NUM) == -1){
        perror("listen error\r\n");
        exit(1);
    }
}



/**
 * server_fd    服务端文件描述符
 * return       客户端文件描述符
*/
int accept_t(int server_fd){
    socklen_t clit_addr_len =  sizeof(struct sockaddr);
    SOCKETADDR_IN 	clit_addr;
    int client_fd = 0;

    char client_IP[128];

    client_fd = accept(server_fd, (struct sockaddr *)&clit_addr, &clit_addr_len);

    if(client_fd == -1){
        perror("accept error\r\n");
        exit(1);
        return -1;
    }else{
        NET_LOG("client ip:%s port:%d\r\n",inet_ntop(IPV4,&clit_addr.sin_addr.s_addr,client_IP,sizeof(client_IP)),ntohs(clit_addr.sin_port));
        return client_fd;
    }

}

/**
 * socket连接初始化
 * demain IPV4与IPv6选择
 * type   连接方式  TCP,UDP
 * return 返回的socket文件描述符
*/
int socket_init(int domain, int type){
    NET_LOG("socket init\r\n");
    int server_fd = socket_t(domain,type);
    bind_t(server_fd,domain,PORT);
    listen_t(server_fd);
    return server_fd;
}


/**
 * epoll初始化函数
 * epoll_def_init   event变量
 * server_fd        socket文件描述符
 * return           epoll_create文件描述符
*/
int epoll_init(EPOLL_DEF *epoll_def_init,int server_fd){
    int epfd=epoll_create(LISTEN_NUM);
    if(epfd == -1){
        perror("epoll_create error:");
        exit(1);
    }
    epoll_def_init->events=EPOLLIN;
    epoll_def_init->data.fd=server_fd;
    //添加socket文件描述符到树中
    epoll_add(epfd,server_fd,epoll_def_init);

    return epfd;
}


/**
 * epoll_add添加文件描述符
 * epfd           epoll_create文件描述符
 * fd             需要添加的文件描述符
 * epoll_def      event变量
*/
void epoll_add(int epfd,int fd,EPOLL_DEF *epoll_def){
    int ep_ctl = epoll_ctl(epfd,EPOLL_CTL_ADD,fd,epoll_def);
     if(ep_ctl == -1){
        perror("epoll_ctl error:");
        exit(1);
    }
}


/**
 * epoll_delete删除文件描述符
 * epfd              epoll_create文件描述符
 * epoll_def         ep[i]变量
 * index             ep的下标
*/
void epoll_delete(int epfd,EPOLL_DEF *epoll_def,int index){
    NET_LOG("epoll_delete %d\r\n",epoll_def[index].data.fd);
    epoll_ctl(epfd,EPOLL_CTL_DEL,epoll_def[index].data.fd,NULL);
    close(epoll_def[index].data.fd);
}

/**
 * 添加accept的文件描述符
 * server_fd    socket文件描述符
 * epoll_def    event变量
 * epfd         epoll_create文件描述符
*/
void epoll_accpet(int server_fd,EPOLL_DEF *epoll_def,int epfd){
    int client_fd = accept_t(server_fd);
    epoll_def->events=EPOLLIN;
    epoll_def->data.fd=client_fd;
    epoll_add(epfd,client_fd,epoll_def);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值