socket编程05: 可交互的客户端与并发服务器

客户端

前面的客户端client_v1.cpp只是发送了一条字符串之后就断开链接,现在我们将其提升(client_v2.cpp),同时用上之前的wrap,使得其可以与服务器交互:

//client_v1.cpp
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <cstdlib>
#include "wrap.h"

#define MAX_LINE 80
#define SERV_PORT 8000

using namespace wrap;

int main(int argc, char *argv[])
{
    sockaddr_in servaddr;
    char buf[MAX_LINE];
    int sockfd;
    ssize_t n;

    sockfd = wrap_socket(AF_INET, SOCK_STREAM, 0);

    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr);
    servaddr.sin_port = htons(SERV_PORT);

    wrap_connect(sockfd, (struct sockaddr *)&servaddr,sizeof(servaddr));

    printf("- - - - - - - - - - - - -\n");
    printf("send: ");
    while(fgets(buf, MAX_LINE, stdin) != NULL)
    {
        wrap_write(sockfd, buf, strlen(buf));
        n = wrap_read(sockfd, buf, MAX_LINE);

        if(n == 0)
            printf("The server has been closed...\n");
        else
        {
            wrap_write(STDOUT_FILENO, "recv: ", 7);
            wrap_write(STDOUT_FILENO, buf, n);
            printf("- - - - - - - - - - - - -\n\n");
        }
        printf("- - - - - - - - - - - - -\n");
        printf("send: ");
    }

    wrap_close(sockfd);
    return 0;
}

服务器

前面的server_v1.cpp只能相应一个客户端,为了让其能够同时响应多个客户端,我们使用fork()新建立多个进程来一一处理(server_v2.cpp):

//server_v2.cpp
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <cctype>

#include "include/wrap.h"

#define MAX_LINE 80
#define SERV_PORT 8000

using namespace wrap;

int main()
{
    sockaddr_in servaddr, cliaddr;
    socklen_t cliaddr_len;
    int listenfd, connfd;
    char buf[MAX_LINE];
    char str[INET_ADDRSTRLEN];
    int i;
    ssize_t n;

    listenfd = wrap_socket(AF_INET, SOCK_STREAM, 0);
    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = htons(SERV_PORT);

    wrap_bind(listenfd, (struct sockaddr *)&servaddr,sizeof(servaddr));
    wrap_listen(listenfd, 20);
    printf("Accepting connections ...\n");

    while (true)
    {
        cliaddr_len = sizeof(cliaddr);
        connfd = wrap_accept(listenfd,
                        (struct sockaddr *)&cliaddr,
                        &cliaddr_len);

        pid_t pid = fork();
        if(pid == -1)
        {
            wrap_perr_exit("call to fork");
        }
        else if(pid == 0)
        {
            wrap_close(listenfd);
            while(true)
            {
                n = wrap_read(connfd, buf, MAX_LINE);
                if(n == 0)
                {
                    printf("The client has been closed...\n\n");
                    break;
                }

                printf("received from %s at PORT %d\n",
                       inet_ntop(AF_INET, &cliaddr.sin_addr, str,sizeof(str)),
                       ntohs(cliaddr.sin_port));

                for (i = 0; i < n; i++)
                    buf[i] = toupper(buf[i]);

                wrap_write(connfd, buf, n);
            }
            wrap_close(connfd);
            exit(0);
        }
        else
            wrap_close(connfd);
    }
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容