连接工具的封装(支持TCP,UDP)的共享文件——network

1.写network.h

#pragma once

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <sys/un.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdbool.h>

typedef struct NetWork
{
    int type;               //通信协议类型
    int sock_fd;            //socket描述符
    struct sockaddr_in addr;//通信地址
    socklen_t addrlen;//通信地址字节数
    bool issvr;//是否是服务器
}NetWork;

typedef struct sockaddr *SP;

//分配内存,创建socket套接字,初始化地址,绑定,监听,连接
NetWork *init_nw(int type,short port,const char *ip,bool issvr);
//等待连接,只有TCP协议的服务器端才能调用
NetWork *accept_nw(NetWork *svr_nw);
//具备send和sendto的功能
int send_nw(NetWork *nw,void *buf,size_t len);
//具备recv和recvfrom的功能
int recv_nw(NetWork *nw,void *buf,size_t len);
//关闭socket对象并释放内存
void close_nw(NetWork *nw);

//获取IP地址
const char *getip_nw(NetWork *nw);

2.写network.c

#include "network.h"

//分配内存,创建socket套接字,初始化地址,绑定,监听,连接
NetWork *init_nw(int type,short port,const char *ip,bool issvr)
{
    NetWork *nw=malloc(sizeof(NetWork));
    nw->sock_fd=socket(AF_INET,type,0);
    if (nw->sock_fd<0)
    {
        free(nw);
        perror("socket");
        return NULL;
    }
    //初始化通信地址
    bzero(&nw->addr,nw->addrlen);
    //准备通信地址
    nw->type=type;
    nw->issvr=issvr;
    nw->addr.sin_family=AF_INET;
    nw->addr.sin_port=htons(port);
    nw->addr.sin_addr.s_addr=inet_addr(ip);
    nw->addrlen=sizeof(struct sockaddr_in);
    //检查是否服务器
    if (issvr)
    {
        if (bind(nw->sock_fd,(SP)&nw->addr,nw->addrlen))
        {
            free(nw);
            perror("bind");
            return NULL;
        }
        //TCP服务器端需要监听
        if (SOCK_STREAM==type&&listen(nw->sock_fd,50))
        {
            free(nw);
            perror("listen");
            return NULL;
        }
        
    }
    else if (SOCK_STREAM==type)//TCP客户端
    {
        if(connect(nw->sock_fd,(SP)&nw->addr,nw->addrlen))
        {
            free(nw);
            perror("connect");
            return NULL;
        }
        
    }
    return nw;
}

//等待连接,只有TCP协议的服务器端才能调用
NetWork *accept_nw(NetWork *svr_nw)
{
    if (SOCK_STREAM!=svr_nw->type || !svr_nw->issvr)
    {
        printf("只有TCP协议且为服务器端的NetWork对象才能调用此函数");
        return NULL;
    }
    //为新的NetWork分配内存并初始化
    NetWork *nw=malloc(sizeof(NetWork));
    nw->addrlen=svr_nw->addrlen;
    nw->type=SOCK_STREAM;
    nw->issvr=true;

    nw->sock_fd=accept(svr_nw->sock_fd,(SP)&nw->addr,&nw->addrlen);
    if (nw->sock_fd<0)
    {
        free(nw);
        perror("accept");
        return NULL;
    }
    return nw;
}

//具备send和sendto的功能
int send_nw(NetWork *nw,void *buf,size_t len)
{
    if (nw->type==SOCK_DGRAM)
    {
        return sendto(nw->sock_fd,buf,len,0,(SP)&nw->addr,nw->addrlen);
    }
    else
    {
        return send(nw->sock_fd,buf,len,0);
    }
}

//具备recv和recvfrom的功能
int recv_nw(NetWork *nw,void *buf,size_t len)
{
    if (nw->type==SOCK_DGRAM)
    {
        return recvfrom(nw->sock_fd,buf,len,0,(SP)&nw->addr,&nw->addrlen);
    }
    else
    {
        return recv(nw->sock_fd,buf,len,0);
    }
}

//关闭socket对象并释放内存
void close_nw(NetWork *nw)
{
    close(nw->sock_fd);
    free(nw);
}

//获取IP地址
const char *getip_nw(NetWork *nw)
{
    return inet_ntoa(nw->addr.sin_addr);
}

3.工具已经封装好了,下面进行使用

写服务器端代码

#include "network.h"

void server(NetWork *fd)
{
    char buf[4096];
    size_t buf_size=sizeof(buf);
    while(1)
    {
        int ret=recv_nw(fd,buf,buf_size);
        if(ret<=0||0==strcmp("quit",buf))
        {
            printf("客户端%d退出\n",fd->sock_fd);
            break;
        }
        printf("from %d recv:%s bits:%d\n",fd->sock_fd,buf,ret);
        strcat(buf,":return");
        ret=send_nw(fd,buf,strlen(buf)+1);
    }
    close_nw(fd);
    exit(0);
}

int main(int argc,const char* argv[])
{
    NetWork *nw=init_nw(SOCK_STREAM,atoi(argv[2]),argv[1],true);
    while(1)
    {
        NetWork *fd=accept_nw(nw);
        if(0==fork()) server(fd);
    }

        
    return 0;
}

写客户端代码

#include "network.h"

int main(int argc,const char* argv[])
{
    NetWork *nw=init_nw(SOCK_STREAM,atoi(argv[2]),argv[1],false);
    char buf[4096];
    size_t buf_size=sizeof(buf);
    while(1)
    {
        printf(">>>>>");
        scanf("%s",buf);
        int ret=send_nw(nw,buf,strlen(buf)+1);
        if(ret<=0||0==strcmp("quit",buf))
        {
            printf("通信结束!\n");
            close_nw(nw);
            break;
        }
    
        ret=recv_nw(nw,buf,buf_size);
        if(ret<=0)
        {
            close_nw(nw);
            break;
        }
        printf("from %d recv:%s bits:%d\n",nw->sock_fd,buf,ret);
    }

        
    return 0;
}

4.

将代码部分完成后,对其进行封装

封装TCP\UDP通用通信代码库:
1、gcc -fpic -c network.c
2、gcc -shared -fpic network.o -o libnetwork.so
3、sudo cp libnetwork.so /usr/lib
4、sudo cp network.h /usr/include/

使用 gcc code.c -lnetwork

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值