网络编程——tcp并发服务器

  • Post author:
  • Post category:其他



多进程

#include <head.h>
#define PORT 8888
#define IP "192.168.31.159"

int work(int newfd, struct sockaddr_in cin_t)
{
    ssize_t res;
    char buf[128];
    while (1)
    {
        bzero(buf, sizeof(buf));
        res = recv(newfd, buf, sizeof(buf), 0);
        if (res == 0)
        {
            printf("服务器断开\n");
            return 0;
        }
        printf("[%s:%d]>>>%s\n", inet_ntoa(cin_t.sin_addr), ntohs(cin_t.sin_port), buf);
        strcat(buf, "*_*");
        send(newfd, buf, sizeof(buf), 0);
    }
}
typedef void(*sighandler_t)(int);
void handler(int sig){
    while(waitpid(-1,NULL,WNOHANG)>0);
}
int main(int argc, const char *argv[])
{
     signal(17,handler);
    //创建流式套接字
    int sfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sfd < 0)
        PRINT_ERR("socket");

    int reuse = 1;
    if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0)
        PRINT_ERR("setsockopt");

    //填充地址信息的结构体,将IP和端口号绑定到套接字上
    struct sockaddr_in sin_t;
    sin_t.sin_family = AF_INET;
    sin_t.sin_port = htons(PORT);
    sin_t.sin_addr.s_addr = inet_addr(IP);
    //绑定服务器的ip和端口
    if (bind(sfd, (struct sockaddr *)&sin_t, sizeof(sin_t)) < 0)
        PRINT_ERR("bind");

    //将套接字设置为监听状态
    if (listen(sfd, 128) < 0)
        PRINT_ERR("listen");
    printf("服务器监听成功\n");
    struct sockaddr_in cin_t;
    socklen_t addrlen = sizeof(cin_t);
    int newfd;
    pid_t pid;
    while (1)
    {
        newfd = accept(sfd, (struct sockaddr *)&cin_t, &addrlen);
        if (newfd < 0)
            PRINT_ERR("accept");
        printf("[%s:%d]成功连接\n", inet_ntoa(cin_t.sin_addr), ntohs(cin_t.sin_port));
        pid=fork();
        if(pid==0){
            close(sfd);
            work(newfd, cin_t);
            close(newfd);
            exit(0);
        }
        close(newfd);
    }
    close(sfd);

    return 0;
}

在这里插入图片描述


多线程

#include <head.h>
#define PORT 8888
#define IP "192.168.31.159"
int sfd;
struct td
{
    int newfd;
    struct sockaddr_in cin_t;
} td_t;
void *callback(void *arg)
{
    struct td *p = (struct td *)arg;
    int newfd = p->newfd;
    struct sockaddr_in cin_t = p->cin_t;
    ssize_t res;
    char buf[128];
    while (1)
    {
        bzero(buf, sizeof(buf));
        res = recv(newfd, buf, sizeof(buf), 0);
        if (res == 0)
        {
            printf("服务器断开,关闭newfd:%d\n", newfd);
            close(newfd);
            break;
        }
        printf("[%s:%d]>>>%s\n", inet_ntoa(cin_t.sin_addr), ntohs(cin_t.sin_port), buf);
        strcat(buf, "*_*");
        send(newfd, buf, sizeof(buf), 0);
    }
}

int main(int argc, const char *argv[])
{
    //创建流式套接字
    sfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sfd < 0)
        PRINT_ERR("socket");

    int reuse = 1;
    if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0)
        PRINT_ERR("setsockopt");

    //填充地址信息的结构体,将IP和端口号绑定到套接字上
    struct sockaddr_in sin_t;
    sin_t.sin_family = AF_INET;
    sin_t.sin_port = htons(PORT);
    sin_t.sin_addr.s_addr = inet_addr(IP);
    //绑定服务器的ip和端口
    if (bind(sfd, (struct sockaddr *)&sin_t, sizeof(sin_t)) < 0)
        PRINT_ERR("bind");

    //将套接字设置为监听状态
    if (listen(sfd, 128) < 0)
        PRINT_ERR("listen");
    printf("服务器监听成功\n");
    socklen_t addrlen = sizeof(td_t.cin_t);
    pthread_t tid;
    while (1)
    {
        td_t.newfd = accept(sfd, (struct sockaddr *)&td_t.cin_t, &addrlen);
        if (td_t.newfd < 0)
            PRINT_ERR("accept");
        printf("[%s:%d]成功连接\n", inet_ntoa(td_t.cin_t.sin_addr), ntohs(td_t.cin_t.sin_port));
        pthread_create(&tid, NULL, callback, (void *)&td_t);
        pthread_detach(tid);
    }
    close(sfd);

    return 0;
}

在这里插入图片描述



版权声明:本文为qq_47837127原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。