9.3tcp多进程并发模板和多线程并发模板


多进程并发模板

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <signal.h>
#include <sys/wait.h>
#include <ctype.h>
#include "wrap.h"

#define MAX_LINE 80
#define SERV_PORT 8000

void do_sig_child(int num)  //通过子进程结束时发送给父进程信号回收子进程
{
    while (waitpid(0, 0, 0) > 0)//阻塞回收
        ;   
}

int main(void)
{
    int servfd, clifd;
    struct sockaddr_in servaddr, cliaddr;
    socklen_t cliaddrlen;
    int i, len;
    pid_t pid;
    char buf[MAX_LINE];
    char str[MAX_LINE];
    struct sigaction act;

    act.sa_handler = do_sig_child;//设置信号捕捉函数
    sigemptyset(&act.sa_mask);
    act.sa_flags = 0;
    sigaction(SIGCHLD, &act, NULL);

    servfd = Socket(AF_INET, SOCK_STREAM, 0);

    bzero(&servaddr, sizeof(servaddr));//初始化服务器地址信息
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(SERV_PORT);
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);

    Bind(servfd, (struct sockaddr *)&servaddr, sizeof(servaddr));//绑定
    Listen(servfd, 20);

    printf("Accepting ...\n");

    while (1) {
        cliaddrlen = sizeof(cliaddr);
        clifd = Accept(servfd, (struct sockaddr *)&cliaddr, &cliaddrlen);

        pid = fork();
        if (pid == 0) { //子进程
            Close(servfd);
            printf("Receving : %s, PORT: %d\n", inet_ntop(AF_INET, &cliaddr.sin_addr, str, sizeof(str)), ntohs(cliaddr.sin_port));

            while (1) {
                len = Read(clifd, buf, sizeof(buf));
                if (len == 0) { //为0时说明客户端关闭连接,跳出循环
                    printf("one client exit\n");
                    break;
                }

                for (i = 0; i < len; i++)
                    buf[i] = toupper(buf[i]);
                Write(clifd, buf, len);
            }

            Close(clifd);
            return 0;//结束子进程
        } else if (pid > 0) {
            Close(clifd);
        } else {
            perr_exit("fock error");
        }
    }

    Close(servfd);
    return 0;
}

多线程并发模板

#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <arpa/inet.h>
#include "wrap.h"
#include <strings.h>
#include <pthread.h>
#include <string.h>
#include <ctype.h>

#define SERV_PORT 8000
#define MAX_LINE 80
int clifd;  //设置全局变量,一遍让线程可以访问

void *th_fun(void *arg)
{
    int clientfd = clifd;
    int i, len;
    char buf[MAX_LINE];

    while (1) {

        len = Read(clientfd, buf, sizeof(buf));
        if (len == 0) {
            printf("one client exit\n");
            break;
        }   
        for (i = 0; i < len; i++)
            buf[i] = toupper(buf[i]);
        Write(clientfd, buf, len);
    }
    Close(clientfd);
    return NULL;
}

int main(void)
{
    int servfd;
    struct sockaddr_in servaddr, cliaddr;
    socklen_t cliaddrlen;
    char str[MAX_LINE];
    pthread_t tid;
    pthread_attr_t attr;
    int n;

    pthread_attr_init(&attr);//设置线程分离属性
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

    servfd = Socket(AF_INET, SOCK_STREAM, 0);

    bzero(&servaddr, sizeof(servaddr));//初始化地址信息
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(SERV_PORT);
    servaddr.sin_addr.s_addr = htons(INADDR_ANY);

    Bind(servfd, (struct sockaddr *)&servaddr, sizeof(servaddr));//绑定

    Listen(servfd, 20);
    printf("Accepting ...\n");
    while (1) {
        cliaddrlen = sizeof(cliaddr);
        clifd = Accept(servfd, (struct sockaddr *)&cliaddr, &cliaddrlen);
        printf("Rece: %s, PORT: %d\n", inet_ntop(AF_INET, &cliaddr.sin_addr, str, sizeof(str)), ntohs(cliaddr.sin_port));

        n = pthread_create(&tid, &attr, th_fun, NULL);//创建线程
        if (n != 0)//出错处理
            fprintf(stderr, "pthread_create:%s\n", strerror(n));

    }
    Close(servfd);

    return 0;
}

wrap函数出错处理

#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
#include <sys/socket.h>
#include <stdio.h>
#include <string.h>
#include <arpa/inet.h>

void perr_exit(const char *str)
{
    perror(str);
    exit(1);
}

int Socket(int family, int type, int protocol)
{
    int n;
    if ((n = socket(family, type, protocol)) < 0)  
        perr_exit("socket error");
    return n;
}

void Bind(int sockfd, const struct sockaddr *sa, socklen_t salen)
{
    if (bind(sockfd, sa, salen) < 0)
        perr_exit("bind error");
}

void Listen(int sockfd, int backlog)
{
    if (listen(sockfd, backlog) < 0)
        perr_exit("listen error");
}

int Accept(int sockfd, struct sockaddr *sa, socklen_t *salenptr)
{
    int n;
    while ((n = accept(sockfd, sa, salenptr)) < 0) {
        if ((errno == ECONNABORTED) || (errno == EINTR))//如果是被信号打断的,重新读取
            ;
        else
            perr_exit("accept error");
    }
    return n;
}

int Read(int fd, void *ptr, int  nbytes)
{
    int  n;
    while ((n = read(fd, ptr, nbytes)) == -1) {
        if (errno == EINTR)//如果是被信号打断的,重新读取
            ;
        else
            return -1;
    }
    return n;
}

int  Write(int fd, const void *ptr, int nbytes)
{
    int n;
    while ((n = write(fd, ptr, nbytes)) == -1) {
        if (errno == EINTR)//如果是被信号打断的,重新写
            ;
        else
            return -1;
    }
    return n;
}

void Close(int fd)
{
    if (close(fd) == -1)
        perr_exit("close error");
}

wrap.h

#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>

#ifndef __WRAP_H_
#define __WRAP_H_

void perr_exit(const char *str);

int Accept(int sockfd, struct sockaddr *sa, socklen_t  *salenptr);

int Socket(int family, int type, int protocol);

void Bind(int sockfd, const struct sockaddr *sa, socklen_t salen);

void Listen(int sockfd, int backlog);

int Read(int fd, void *ptr, int nbytes);

int Write(int fd, const void *ptr, int nbytes);

void Close(int fd);

#endif

客户端

#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <strings.h>
#include "wrap.h"

#define SERV_PORT 8000
#define SERV_IP "192.168.188.133"   
#define MAX_LINE 80

int main(void)
{
    int servfd;
    struct sockaddr_in servaddr;
    int len;
    char buf[MAX_LINE];

//  while (1) {
    servfd = Socket(AF_INET, SOCK_STREAM, 0); 

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

    connect(servfd, (struct sockaddr *)&servaddr, sizeof(servaddr));


    while (1) {
        len = Read(STDIN_FILENO, buf, sizeof(buf));

        Write(servfd, buf, len);
//      Write(servfd, "hello", 5);
        len = Read(servfd, buf, sizeof(buf));
        Write(STDOUT_FILENO, buf, len);
    }

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值