• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    学习Linux网络编程基本函数

    1,创建套接字socket

    函数原型:

    #includesys/types.h>
    #includesys/socket.h>
    int socket(int domain, int type, int protocol);

    参数列表:

    domain参数有以下这些值

    AF_INET:IPv4协议
    AF_INET6:IPv6协议
    AF_LOCAL:Unix域协议
    AF_ROUTE:路由套接口
    AF_KEY:密钥套接口

    type的值:

    SOCKET_STREAM:双向可靠数据流,对应TCPSOCKET_DGRAM:双向不可靠数据报,对应UDPSOCKET_RAW:提供传输层以下的协议,可以访问内部网络接口,例如接收和发送ICMP报文

    protocol得值:

    type为SOCKET_RAW时需要设置此值说明协议类型,其他类型设置为0即可

    函数的作用是创建一个指定格式的套接字并返回其描述符,成功返回描述符,失败返回-1;

    2,绑定套接字bind

    函数原型:

    #includesys/types.h>
    #includesys/socket.h>
    int bind(int sockfd, const struct sockaddr *my_addr, socklen_t addrlen);

    参数列表:

    sockfd为之前创建的套接字描述符

    my_addr是一个通用套接字结构体指针,在做tcp协议编程时通常使用sockaddr_in结构体

    该结构体内容如下;

    struct socketaddr_in
    {
       unsigned short int sin_family;//对应地址族IP v4填AF_INTE
       uint16_t sin_port;//对应端口号
       struct in_addr sin_addr;//对应ip地址
       unsigned char sin_zero[8];
    };
    struct in_addr
    {
       uint32_t s_addr;
    };

    addrlen为该上述结构体的大小,可以用sizeof求得;

    在使用bind函数前需要先创建一个sockaddr_in类型的结构体,将服务器的信息保存到结构体中,

    然后将创建的套接字与之绑定;成功返回0,失败返回-1;

    在设置端口号和IP时先将结构体清空,如果是主函数传参,那么对应的端口号和ip都是字符串格式,

    需要用函数转换,转换格式如下:

    char port[]="8888"
    char ip[]="192.168.1.1"
    struct sockaddr_in seraddr'
    seraddr.sin_port=htos(atoi(port))
    seraddr.sin_addr.s_addr=inet_addr(ip);

    3,创建监听;listen

    函数原型:

    int listen(int fd, int backlog);

    参数列表:

    fd为要监听的套接字描述符;backlog为监听队列的大小;

    (1) 执行listen 之后套接字进入被动模式。

    (2) 队列满了以后,将拒绝新的连接请求。客户端将出现连接D 错误WSAECONNREFUSED。

    (3) 在正在listen的套接字上执行listen不起作用。

    4,等待连接accept

    函数原型:

    #include sys/socket.h>
     int accept(int s, struct sockaddr * addr, int * addrlen);

    对比bind函数可以发现两者的参数几乎一样,但是accept中的addr不被const修饰,

    也就是说addr是用来保存连接的客户端的地址信息的,同杨addlen时返回的addr的大小;

    所以accept函数的作用就是返回已连接的客户端的文件描述符,

    并将客户端的地址信息保存在一个新的sockaddr_in结构体中;链接失败返回-1;

    5, 收发消息send和recv

    函数原型:

      int send( SOCKET s, const char FAR *buf, int len, int flags );
      int recv( SOCKET s, char FAR *buf, int len, int flags); 

    该函数的参数:

    send的流程:

    这里只描述同步Socket的send函数的执行流程。

    当调用该函数时,send先比较待发送数据的长度len和套接字s的发送缓冲的长度,

    要注意send函数把buf中的数据成功copy到s的发送缓冲的剩余空间里后它就返回了,但是此时这些数据并不一定马上被传到连接的另一端。

    recv的流程:

    这里只描述同步Socket的recv函数的执行流程。

    当应用程序调用recv函数时,recv先等待s的发送缓冲中的数据被协议传送完毕,

    (注意协议接收到的数据可能大于buf的长度,所以在这种情况下要调用几次recv函数才能把s的接收缓冲中的数据copy完。

    recv函数仅仅是copy数据,真正的接收数据是协议来完成的),recv函数返回其实际copy的字节数。

    但由于发送缓存的存在,表现为:如果发送缓存大小比请求发送的大小要大,那么send函数立即返回,同时向网络中发送数据;

    否则,send向网络发送缓存中不能容纳的那部分数据,并等待对端确认后再返回(接收端只要将数据收到接收缓存中,

    就会确认,并不一定要等待应用程序调用recv);

    5,关闭套接字描述符close

    函数:

    close(sockfd);

    和文件操作一样,套接字也是一个文件,使用完之后要关闭;

    6,基于tcp协议的C/S服务器模型

    图解tcp模型

    7,实现代码

    服务端:

    #include stdio.h>
    #include stdlib.h>
    #include strings.h>
    #include sys/types.h>
    #include sys/socket.h>
    #include netinet/in.h>
    #include netinet/ip.h>
    #include arpa/inet.h>
    #include unistd.h>
     
    typedef struct sockaddr_in SIN;
    typedef struct sockaddr SA;
     
    int main(int argc,char *argv[])
    {
        SIN seraddr;
        SIN cliaddr;
        int len=sizeof(SIN);
        //创建监听套接字
        int lisfd=socket(AF_INET,SOCK_STREAM,0);
        if(lisfd0)
        {
            perror("socket");
            exit(0);
        }
        printf("创建套接字%d成功\n",lisfd);
        bzero(seraddr,sizeof(seraddr));
        seraddr.sin_family=AF_INET;
        seraddr.sin_port=htons(8888);
        seraddr.sin_addr.s_addr=inet_addr("192.168.1.6");
        //绑定套接子
        int ret=bind(lisfd,(SA*)(seraddr),len);
        if(ret0)
        {
            perror("bind");
            exit(0);
        }
        printf("绑定成功\n");
        //开始监听
        ret=listen(lisfd,1024);
        if(ret0)
        {
            perror("listen");
            exit(0);
        }
        printf("监听成功\n");
        //等待连接,将连接的套接字信息保存
        int clifd=accept(lisfd,(SA*)(cliaddr),(socklen_t *)(len));
        if(clifd0)
        {
            perror("accept");
            exit(0);
        }
        printf("客户端%d连接成功\n",clifd);
        //读写
        char readbuf[1024]={0};
        char sendbuf[1024]={0};
        while(1)
        {
            recv(clifd,readbuf,sizeof(readbuf),0);
            printf("recv:%s\n",readbuf);
            fgets(sendbuf,sizeof(sendbuf),stdin);
            send(clifd,sendbuf,sizeof(sendbuf),0);
        }
        //关闭套接字
        close(clifd);
        close(lisfd);
        return 0;
    }

    客户端:

    #include stdio.h>
    #include stdlib.h>
    #include strings.h>
    #include sys/types.h>
    #include sys/socket.h>
    #include netinet/in.h>
    #include netinet/ip.h>
    #include arpa/inet.h>
    #include unistd.h>
     
    typedef struct sockaddr_in SIN;
    typedef struct sockaddr SA;
     
    int main(int argc,char *argv[])
    {
        SIN seraddr;
        //创建监听套接字
        int serfd=socket(AF_INET,SOCK_STREAM,0);
        if(serfd0)
        {
            perror("socket");
            exit(0);
        }
        printf("创建套接字%d成功\n",serfd);
        bzero(seraddr,sizeof(seraddr));
        seraddr.sin_family=AF_INET;
        seraddr.sin_port=htons(8888);
        seraddr.sin_addr.s_addr=inet_addr("192.168.1.6");
        //请求连接
        int ret=connect(serfd,(SA*)(seraddr),sizeof(SIN));
        if(ret==-1)
        {
            perror("connect");
            exit(0);
        }
        printf("连接成功\n");
        //读写
        char senbuf[1024]={0};
        char readbuf[1024]={0};
        while(1)
        {
            fgets(senbuf,sizeof(senbuf),stdin);
            send(serfd,senbuf,sizeof(senbuf),0);
            recv(serfd,readbuf,sizeof(readbuf),0);
            printf("recv:%s\n",readbuf);
        }
        //关闭套接字
        close(serfd);
        return 0;
    }

    以上就是学习Linux网络编程基本函数的详细内容,更多关于Linux网络编程基本函数的资料请关注脚本之家其它相关文章!

    您可能感兴趣的文章:
    • 简析Linux网络编程函数
    • Linux网络编程之基于UDP实现可靠的文件传输示例
    • Linux网络编程之UDP Socket程序示例
    • Linux网络编程之socket文件传输示例
    • linux网络编程用到的网络函数详解用和使用示例
    上一篇:Linux网络设置详情
    下一篇:Linux自定义防误删脚本的思路与测试
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

    学习Linux网络编程基本函数 学习,Linux,网络编程,基本,