套接字(C语言代码演示)

目录

TCP

服务端

多进程

多线程

线程池

epoll+线程池

客户端

UDP

服务端

客户端


TCP

服务端

多进程

#include<stdio.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<netinet/ip.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<sys/socket.h>
#include<strings.h>
#include<unistd.h>
#include<ctype.h>
#include<stdlib.h>
#include<string.h>
#define SERV_PORT 9000
#define MAXLINE 80
#define pexit(msg) { \
    perror(msg); \
    exit(1); \
}

int main() {

    struct sockaddr_in serveraddr, clientaddr;
    int listenfd, connfd;
    socklen_t clientaddr_len;

    char buf[MAXLINE];
    char str[INET_ADDRSTRLEN];
    int n;

    listenfd = socket(AF_INET, SOCK_STREAM, 0);
    if (listenfd < 0) pexit("socket");

    bzero(&serveraddr, sizeof(serveraddr));
    serveraddr.sin_family=AF_INET;
    serveraddr.sin_port=htons(SERV_PORT);
    serveraddr.sin_addr.s_addr=htonl(INADDR_ANY);

    if (bind(listenfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0) pexit("bind");

    if (listen(listenfd, 3) < 0) pexit("listen");
    printf("%s\n", "Waiting to be conneted...");

    while(1) {
        clientaddr_len = sizeof(clientaddr);
        connfd=accept(listenfd, (struct sockaddr *)&clientaddr, &clientaddr_len);
        if (connfd < 0) pexit("accept");
        printf("%s:%d connected\n",
            inet_ntop(AF_INET, &clientaddr.sin_addr, str,sizeof(str)), 
            ntohs(clientaddr.sin_port)
        );
        pid_t pid = fork();
        if (pid <0) pexit("fork");
        
        if (pid > 0) {
            close(connfd);
            while(waitpid(-1, NULL, WNOHANG)>0){}
            continue; 
        }

        close(listenfd);
        while(1) {
            n = read(connfd, buf, MAXLINE);
            if (!strncmp(buf, "quit", 4)) break;
            write(1, buf, n);
            for(int i = 0; i < n; i++) buf[i]=toupper(buf[i]);
        
            write(connfd, buf, n);
        }
        close(connfd);
        printf("%s:%d disconnect\n",
            inet_ntop(AF_INET, &clientaddr.sin_addr, str,sizeof(str)), 
            ntohs(clientaddr.sin_port)
        );
        return 0;

    }

    return 0;
}

多线程

#include<stdio.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<netinet/ip.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<sys/socket.h>
#include<strings.h>
#include<unistd.h>
#include<ctype.h>
#include<stdlib.h>
#include<string.h>
#include<pthread.h>
#define SERV_PORT 9000
#define MAXLINE 80
#define pexit(msg) { \
    perror(msg); \
    exit(1); \
}

struct sockaddr_in serveraddr;
char buf[MAXLINE];
char str[INET_ADDRSTRLEN];
typedef struct ARG{
    int connfd;
    struct sockaddr_in clientaddr;
}ARG;


void *up_server(void *context) {
    pthread_detach(pthread_self());
    char str[INET_ADDRSTRLEN];
    ARG arg = *((ARG *)context);
    int n;
    while(1) {
        n = read(arg.connfd, buf, MAXLINE);
        if (!strncmp(buf, "quit", 4)) break;
        write(1, buf, n);
        for(int i = 0; i < n; i++) buf[i]=toupper(buf[i]);
        write(arg.connfd, buf, n);
    }
    close(arg.connfd);
    printf("%s:%d disconnect\n",
        inet_ntop(AF_INET, &arg.clientaddr.sin_addr, str,sizeof(str)), 
        ntohs(arg.clientaddr.sin_port)
    );
    return (void *)0;

}


int main() {

    int listenfd, connfd;
    socklen_t clientaddr_len;

    int n;

    listenfd = socket(AF_INET, SOCK_STREAM, 0);
    if (listenfd < 0) pexit("socket");

    bzero(&serveraddr, sizeof(serveraddr));
    serveraddr.sin_family=AF_INET;
    serveraddr.sin_port=htons(SERV_PORT);
    serveraddr.sin_addr.s_addr=htonl(INADDR_ANY);

    if (bind(listenfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0) pexit("bind");

    if (listen(listenfd, 3) < 0) pexit("listen");
    printf("%s\n", "Waiting to be conneted...");
    struct sockaddr_in clientaddr;
    while(1) {
        clientaddr_len = sizeof(clientaddr);
        connfd=accept(listenfd, (struct sockaddr *)&clientaddr, &clientaddr_len);
        if (connfd < 0) pexit("accept");
        printf("%s:%d connected\n",
            inet_ntop(AF_INET, &clientaddr.sin_addr, str,sizeof(str)), 
            ntohs(clientaddr.sin_port)
        );

        pthread_t tid;
        ARG arg = {connfd, clientaddr};
        pthread_create(&tid, NULL, up_server, (void *)&arg);
        printf("make a new thread: %#lx\n", tid);

    }

    return 0;
}

线程池

#include<stdio.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<netinet/ip.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<sys/socket.h>
#include<strings.h>
#include<unistd.h>
#include<ctype.h>
#include<stdlib.h>
#include<string.h>
#include<pthread.h>
#define SERV_PORT 9000
#define MAXLINE 80
#define pexit(msg) { \
    perror(msg); \
    exit(1); \
}

struct sockaddr_in serveraddr;
char buf[MAXLINE];
char str[INET_ADDRSTRLEN];

typedef struct Task{
    int fd;
    struct sockaddr_in clientaddr;
    struct Task *next;
} Task;

typedef struct Task_queue {
    Task *head;
    Task *tail;
    pthread_mutex_t lock;
    pthread_cond_t havetask;
}Task_queue;

Task_queue *Task_queue_init() {
    Task_queue *tq = (Task_queue *)malloc(sizeof(Task_queue));
    tq->head = NULL;
    tq->tail = NULL;
    pthread_mutex_init(&tq->lock, NULL);
    pthread_cond_init(&tq->havetask, NULL);

    return tq;
}

void Task_queue_push(Task_queue *tq, int fd, struct sockaddr_in clientaddr) {
    pthread_mutex_lock(&tq->lock);

    Task *t = (Task *)malloc(sizeof(Task));
    t->fd = fd;
    t->clientaddr = clientaddr;
    t->next = NULL;
    if (!tq->tail) {
        tq->head = tq->tail = t;
    } else {
        tq->tail->next = t;
        tq->tail = t;
    }
    
    pthread_cond_broadcast(&tq->havetask);
    pthread_mutex_unlock(&tq->lock);
    return ;
}

Task Task_queue_pop(Task_queue *tq) {
    pthread_mutex_lock(&tq->lock);
    
    while (tq->head == NULL) {
        pthread_cond_wait(&tq->havetask, &tq->lock);
    }


    Task tmp, *k;
    k = tq->head;
    tmp = *k;
    tq->head = tq->head->next;
    
    if (!tq->head) {
        tq->tail = NULL;
    }

    free(k);

    pthread_mutex_unlock(&tq->lock);
    return tmp;
}

void Task_queue_free(Task_queue *tq) {
    pthread_mutex_lock(&tq->lock);
    
    Task *p  = tq->head, *k;
    while (p) {
        k = p;
        p = p->next;
        free(k);
    }
    tq->head = tq->tail = NULL;

    pthread_mutex_unlock(&tq->lock);
    pthread_mutex_destroy(&tq->lock);
    pthread_cond_destroy(&tq->havetask);

    free(tq);
    return ;
}


void *up_server(void *arg) {
    pthread_detach(pthread_self());
    char str[INET_ADDRSTRLEN];
    int n;
    
    Task_queue *tq = arg;
    while(1) {
        Task tmp = Task_queue_pop(tq);
        int connfd = tmp.fd;

        while(1) {
            n = read(connfd, buf, MAXLINE);
            if (!strncmp(buf, "quit", 4)) break;
            write(1, buf, n);
            for(int i = 0; i < n; i++) buf[i]=toupper(buf[i]);
            write(connfd, buf, n);
        }
        close(connfd);
        printf("%s:%d disconnect\n",
            inet_ntop(AF_INET, &tmp.clientaddr.sin_addr, str,sizeof(str)), 
            ntohs(tmp.clientaddr.sin_port)
        );
    }
    return (void *)0;

}


int main() {

    int listenfd, connfd;
    socklen_t clientaddr_len;

    int n;
    Task_queue *tq = Task_queue_init();
    
    pthread_t tid;
    for (int i = 0; i < 4; i++) {
        pthread_create(&tid, NULL, up_server, (void *)tq);
        printf("make a new thread: %#lx\n", tid);
    }

    listenfd = socket(AF_INET, SOCK_STREAM, 0);
    if (listenfd < 0) pexit("socket");

    bzero(&serveraddr, sizeof(serveraddr));
    serveraddr.sin_family=AF_INET;
    serveraddr.sin_port=htons(SERV_PORT);
    serveraddr.sin_addr.s_addr=htonl(INADDR_ANY);

    if (bind(listenfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0) pexit("bind");

    if (listen(listenfd, 3) < 0) pexit("listen");
    printf("%s\n", "Waiting to be conneted...");
    struct sockaddr_in clientaddr;
    while(1) {
        clientaddr_len = sizeof(clientaddr);
        connfd=accept(listenfd, (struct sockaddr *)&clientaddr, &clientaddr_len);
        if (connfd < 0) pexit("accept");
        printf("%s:%d connected\n",
            inet_ntop(AF_INET, &clientaddr.sin_addr, str,sizeof(str)), 
            ntohs(clientaddr.sin_port)
        );
        Task_queue_push(tq, connfd, clientaddr);

    }
    
    Task_queue_free(tq);
    return 0;
}

epoll+线程池

#include<stdio.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<netinet/ip.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<sys/socket.h>
#include<sys/epoll.h>
#include<strings.h>
#include<unistd.h>
#include<ctype.h>
#include<stdlib.h>
#include<string.h>
#include<pthread.h>
#define SERV_PORT 9000
#define MAXLINE 8000
#define pexit(msg) { \
    perror(msg); \
    exit(1); \
}

struct sockaddr_in serveraddr;
char buf[MAXLINE];
char str[INET_ADDRSTRLEN];

typedef struct Task{
    int fd;
    struct sockaddr_in clientaddr;
    struct Task *next;
} Task;

typedef struct Task_queue {
    Task *head;
    Task *tail;
    pthread_mutex_t lock;
    pthread_cond_t havetask;
}Task_queue;

Task_queue *Task_queue_init() {
    Task_queue *tq = (Task_queue *)malloc(sizeof(Task_queue));
    tq->head = NULL;
    tq->tail = NULL;
    pthread_mutex_init(&tq->lock, NULL);
    pthread_cond_init(&tq->havetask, NULL);

    return tq;
}

void Task_queue_push(Task_queue *tq, int fd, struct sockaddr_in clientaddr) {
    pthread_mutex_lock(&tq->lock);

    Task *t = (Task *)malloc(sizeof(Task));
    t->fd = fd;
    t->clientaddr = clientaddr;
    t->next = NULL;
    if (!tq->tail) {
        tq->head = tq->tail = t;
    } else {
        tq->tail->next = t;
        tq->tail = t;
    }
    
    pthread_cond_broadcast(&tq->havetask);
    pthread_mutex_unlock(&tq->lock);
    return ;
}

Task Task_queue_pop(Task_queue *tq) {
    pthread_mutex_lock(&tq->lock);
    
    while (tq->head == NULL) {
        pthread_cond_wait(&tq->havetask, &tq->lock);
    }


    Task tmp, *k;
    k = tq->head;
    tmp = *k;
    tq->head = tq->head->next;
    
    if (!tq->head) {
        tq->tail = NULL;
    }

    free(k);

    pthread_mutex_unlock(&tq->lock);
    return tmp;
}

void Task_queue_free(Task_queue *tq) {
    pthread_mutex_lock(&tq->lock);
    
    Task *p  = tq->head, *k;
    while (p) {
        k = p;
        p = p->next;
        free(k);
    }
    tq->head = tq->tail = NULL;

    pthread_mutex_unlock(&tq->lock);
    pthread_mutex_destroy(&tq->lock);
    pthread_cond_destroy(&tq->havetask);

    free(tq);
    return ;
}


void *up_server(void *arg) {
    pthread_detach(pthread_self());
    char str[INET_ADDRSTRLEN];
    int n;
    
    Task_queue *tq = arg;
    while(1) {
        Task tmp = Task_queue_pop(tq);
        int connfd = tmp.fd;
        
        n = read(connfd, buf, MAXLINE);
        write(1, buf, n);
        if (!strncmp(buf, "quit", 4)) {
            close(connfd);
            printf("%s:%d disconnect\n",
                inet_ntop(AF_INET, &tmp.clientaddr.sin_addr, str,sizeof(str)), 
                ntohs(tmp.clientaddr.sin_port)
            );
        } else {
            for(int i = 0; i < n; i++) buf[i]=toupper(buf[i]);
            write(connfd, buf, n);
        }
    }
    return (void *)0;

}


int main() {

    int listenfd, connfd;
    socklen_t clientaddr_len;

    int n;
    Task_queue *tq = Task_queue_init();
    
    pthread_t tid;
    for (int i = 0; i < 4; i++) {
        pthread_create(&tid, NULL, up_server, (void *)tq);
        printf("make a new thread: %#lx\n", tid);
    }

    listenfd = socket(AF_INET, SOCK_STREAM, 0);
    if (listenfd < 0) pexit("socket");

    int epfd = epoll_create(256);
    struct epoll_event ev, events[256];
    ev.events = EPOLLIN | EPOLLET;
    ev.data.fd = listenfd;
    epoll_ctl(epfd, EPOLL_CTL_ADD, listenfd, &ev);

    bzero(&serveraddr, sizeof(serveraddr));
    serveraddr.sin_family=AF_INET;
    serveraddr.sin_port=htons(SERV_PORT);
    serveraddr.sin_addr.s_addr=htonl(INADDR_ANY);

    if (bind(listenfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0) pexit("bind");

    if (listen(listenfd, 3) < 0) pexit("listen");
    printf("%s\n", "Waiting to be conneted...");
    struct sockaddr_in clientaddr;
    while(1) {
        int nfds = epoll_wait(epfd, events, 256, -1);
        for (int i = 0; i < nfds; i++) {
            if(events[i].data.fd == listenfd) {
                clientaddr_len = sizeof(clientaddr);
                connfd=accept(listenfd, (struct sockaddr *)&clientaddr, &clientaddr_len);
                if (connfd < 0) pexit("accept");
                printf("%s:%d connected\n",
                    inet_ntop(AF_INET, &clientaddr.sin_addr, str,sizeof(str)), 
                    ntohs(clientaddr.sin_port)
                );
                ev.events = EPOLLIN | EPOLLET;
                ev.data.fd = connfd;
                epoll_ctl(epfd, EPOLL_CTL_ADD, connfd, &ev);
            } else if (events[i].events & EPOLLIN) {
                int clientfd = events[i].data.fd;
                if (clientfd < 3) continue;
                getpeername(clientfd, (struct sockaddr *)&clientaddr, &clientaddr_len);
                Task_queue_push(tq, clientfd, clientaddr);
            }
        }

    }
    
    Task_queue_free(tq);
    return 0;
}

客户端

#include<stdio.h>
#include<stdio.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<netinet/ip.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<strings.h>
#include<unistd.h>
#include<ctype.h>
#include<string.h>
#define SERV_PORT 9000
#define MAXLINE 80

int main() {
    struct sockaddr_in serveraddr;
    char buf[MAXLINE] = {"hello\n"};
    int connfd = socket(AF_INET, SOCK_STREAM, 0); 

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

    connect(connfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr));
    int n;
    while (n=read(0, buf, MAXLINE)) {
        write(connfd, buf, n);
        if (!strncmp(buf, "quit", 4)) break;
    
        int n = read(connfd, buf, MAXLINE);
        printf("response from server:\n");
        write(1, buf, n);
    
    }
    close(connfd);

    return 0;
}

UDP

服务端

#include<stdio.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<netinet/ip.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<sys/socket.h>
#include<strings.h>
#include<unistd.h>
#include<ctype.h>
#include<stdlib.h>
#include<string.h>
#include<pthread.h>

#define SERV_PORT 9000
#define MAXLINE 80
#define pexit(msg) { \
    perror(msg); \
    exit(1); \
}

int main() {
    int sockfd;
    struct sockaddr_in serveraddr, clientaddr;
    char buf[MAXLINE];
    char str[INET_ADDRSTRLEN];
    socklen_t clientaddr_len;

    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    
    bzero(&serveraddr, sizeof(serveraddr));
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
    serveraddr.sin_port = htons(SERV_PORT);
    
    bind(sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr));
    printf("Wating to receive data...\n");

    int n;
    while(1) {
        n = recvfrom(sockfd, buf, MAXLINE, 0, (struct sockaddr *)&clientaddr, &clientaddr_len);
        if (n < 0) pexit("recvfrom");

        printf("received from %s:%d\n", 
            inet_ntop(AF_INET, &clientaddr.sin_addr, str, sizeof(str)), 
            ntohs(clientaddr.sin_port));
        write(1, buf, n);
        for (int i = 0; i < n; i++) buf[i] = toupper(buf[i]);
        sendto(sockfd, buf, n, 0, (struct sockaddr *)&clientaddr, sizeof(clientaddr));

    }
    
    close(sockfd);

    return 0;
}

客户端

#include<stdio.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<netinet/ip.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<sys/socket.h>
#include<strings.h>
#include<unistd.h>
#include<ctype.h>
#include<stdlib.h>
#include<string.h>
#include<pthread.h>

#define SERV_PORT 9000
#define MAXLINE 80
#define pexit(msg) { \
    perror(msg); \
    exit(1); \
}


int main() {
    struct sockaddr_in serveraddr;
    int sockfd;
    int n;
    char buf[MAXLINE] = "hello\n";
    
    sockfd = socket(AF_INET, SOCK_DGRAM, 0);

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

    if (sendto(sockfd, buf, sizeof(buf), 0, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0) pexit("sendto");
    while(n = read(0, buf, MAXLINE)) {
        n = sendto(sockfd, buf, n, 0, (struct sockaddr *)&serveraddr, sizeof(serveraddr));
        n = recvfrom(sockfd, buf, MAXLINE, 0, NULL, 0);
        write(1, buf, n);
    }

    close(sockfd);

    return 0;
}

  • 7
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值