• Linux-网络编程(day13)


     一、基于TCP的网络编程(续day12)

    二、并发服务器

    三、基于UDP的网络编程


      一、基于TCP的网络编程(续day12)

      1、昨天的例子客户端只能向指定的服务器端发送数据,可以利用主函数参数传递命令行参数,从而接收任意服务器地址。同时也可以实现两台机器之间的通信(可以事先使用ping命令查看是否通)

      2、也可以使用while循环在客户端不断接收数据输入,知道特定字符结束输入关闭通讯,如使用fgets,或gets

    #if 0

    ...

    #endif

    可以进行条件注释

    基于TCP的服务器:

    #include <stdio.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <string.h>
    #include <arpa/inet.h>
    int main()
    {
    int listenfd = socket (AF_INET, SOCK_STREAM, 0);
    if (listenfd == -1)
        {
            perror ("socket");
            exit (EXIT_FAILURE);
        }
    struct sockaddr_in addr;
        addr.sin_family = AF_INET;
        addr.sin_port = htons (8888);
        addr.sin_addr.s_addr = INADDR_ANY;
    if (bind (listenfd, (struct sockaddr*)&addr, sizeof (addr)) == -1)
        {
            perror ("bind");
            exit (EXIT_FAILURE);
        }
    if (listen (listenfd, 1024) == -1)
        {
            perror ("listen");
            exit (EXIT_FAILURE);
        }
    struct sockaddr_in addrcli = {};
        socklen_t addrlen = sizeof (addrcli);
    int connfd = accept (listenfd, (struct sockaddr*)&addrcli, &addrlen);
    if (connfd == -1)
        {
            perror ("accept");
            exit (EXIT_FAILURE);
        }
        printf ("服务器已接受来自%s:%hu客户机的连接请求
    ", inet_ntoa (addrcli.sin_addr),ntohs (addrcli.sin_port));
    char buf[1024];
        ssize_t rcvd = recv (connfd, buf, sizeof (buf), 0);
    if (rcvd == -1)
        {
            perror ("recv");
            exit (EXIT_FAILURE);
        }
    if (rcvd == 0)
        {
            printf ("客户机已关闭连接
    ");
            exit (EXIT_FAILURE);
        }
        buf[rcvd] = '';
        printf ("客户端说:%s
    ", buf);
        printf ("服务器说:");
        gets (buf);
        ssize_t sent = send (connfd, buf, strlen (buf) * sizeof (buf[0]), 0);
    if (sent == -1)
        {
            perror ("send");
            exit (EXIT_FAILURE);
        }
    if (close (listenfd) == -1)
        {
            perror ("close");
            exit (EXIT_FAILURE);
        }
    if (close (connfd) == -1)
        {
            perror ("close");
            exit (EXIT_FAILURE);
        }
    return 0;
    }

     基于TCP的客户端:

    #include <stdio.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <string.h>
    #include <arpa/inet.h>
    int main()
    {
    int listenfd = socket (AF_INET, SOCK_STREAM, 0);
    if (listenfd == -1)
        {
            perror ("socket");
            exit (EXIT_FAILURE);
        }
    struct sockaddr_in addr;
        addr.sin_family = AF_INET;
        addr.sin_port = htons (8888);
        addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    if (connect (listenfd, (struct sockaddr*)&addr, sizeof (addr)) == -1)
        {
            perror ("connect");
            exit (EXIT_FAILURE);
        }
    char buf[1024] = "你好,服务器";
        printf ("客户端说:%s
    ", buf);
        ssize_t sent = send (listenfd, buf, strlen (buf) * sizeof (buf[0]), 0);
    if (sent == -1)
        {
            perror ("send");
            exit (EXIT_FAILURE);
        }
        ssize_t rcvd = recv (listenfd, buf, sizeof (buf), 0);
    if (rcvd == -1)
        {
            perror ("recv");
            exit (EXIT_FAILURE);
        }
        buf[rcvd] = '';
        printf ("服务器说:%s
    ", buf);
    if (close (listenfd) == -1)
        {
            perror ("close");
            exit (EXIT_FAILURE);
        }
    return 0;
    }

     上述服务器只能给一个客户端提供服务,这就需要后面讲到的并发来解决。

    可以使用setsockopt(2)来设置socket属性,或者getsockopt(2)来获取socket属性。


    二、并发服务器

    1、使用线程实现并发服务器

    2、多路复用计数实现并发服务器

      select(2)、poll(2)等

    3、使用多进程实现并发服务器

      在这里需要分清楚,父进程,子进程的作用,以及fork的时机。

  • 相关阅读:
    javascript中构造函数与普通函数的区别还有关于“new”操作符的一些原理
    一个简单的jquery左右列表内容切换应用
    Spring学习笔记(三)之装配Bean
    Maven引入jar的总结
    在使用hibernate的getHibernateTemplate()时怎么让控制台输出封装好的SQL? 怎么用日志打印出来?
    Spring学习笔记(二)之装配Bean
    spring学习笔记(一) Spring概述
    ResourceBundle读取文件学习
    如何从结果集中遍历得到一条条的数据?
    response与request回顾学习
  • 原文地址:https://www.cnblogs.com/ptfe/p/11070303.html
Copyright © 2020-2023  润新知