基于socket的简单tcp客户端与服务端程序

    xiaoxiao2021-04-14  86

    基于socket的简单tcp客户端与服务端程序

    前一段时间,我实习所在公司的同事说想学习网络编程的知识,我向他介绍了我学习网络编程的历程,在此给大家分享一下,希望能给刚入门的小伙伴带来帮助。我当时学网络编程时,没有志同道合的小伙伴,没有专业的导师教导,自己在这个过程中摸索前行,其中的困难只有自己清楚。

    自己的学习历程:

    1,window网络编程带我入门,发现自己写的程序竟然可以在网络上通讯,当时感觉很神奇,由此激发我学习网络编程的兴趣。 2,渐渐的发现window网络编程的API满足不了我的需求,然后就转到Linux/Unix网络编程。 3,在实验室所谓的项目组(就我一个人)首次接触到了epoll。

    在Linux下学习Linux/Unix网络编程,我的学习过程是按照下面的模式循序渐进的:

    1个服务端对应1个客户端

    1个服务端对应n个客户端

    分别使用select,poll,epoll实现1个服务端对应n个客户端。 分析select,poll,epoll三者有何不同?

    下面给大家分享一个基于socket的简单tcp客户端与服务端程序, 回头有时间再分享一个http下载服务器程序到github。

    makefile

    all: rm -rf server rm -rf client gcc -Wall -g server.c -o server gcc -Wall -g client.c -o client

    服务端程序

    #include <stdio.h> #include <string.h> #include <unistd.h> #include <errno.h> #include <arpa/inet.h> #include <stdlib.h> #define BUFFSIZE 20480 #define BACKLOG 100 int main(int argc, char **argv) { int flag; int clientfd; int listenfd = 0; int reuse = 1; int addrlen; char buff[BUFFSIZE]; struct sockaddr_in addr; struct sockaddr_in cliaddr; addrlen = sizeof(struct sockaddr_in); if (argc < 2) { printf("Usage: %s ip port\n", argv[0]); goto end; } memset(&addr, 0, addrlen); addr.sin_family = AF_INET; addr.sin_port = htons(atoi(argv[2])); addr.sin_addr.s_addr = inet_addr(argv[1]); listenfd = socket(AF_INET, SOCK_STREAM, 0); if (listenfd == -1) { printf("fail in socket(), errno : %d, %s\n", errno, strerror(errno)); goto end; } if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) == -1) { printf("fail in setsockopt(), errno : %d, %s\n", errno, strerror(errno)); goto end; } if ((bind(listenfd, (const struct sockaddr *)&addr, addrlen)) == -1) { printf("fail in bind(), errno : %d, %s\n", errno, strerror(errno)); goto end; } if (listen(listenfd, BACKLOG) == -1) { printf("fail in listen(), errno : %d, %s\n", errno, strerror(errno)); goto end; } while (1) { printf("waiting client connect...\n"); memset(&cliaddr, 0, addrlen); clientfd = accept(listenfd, (struct sockaddr *)&cliaddr, (socklen_t *)&addrlen); if (clientfd == -1) { printf("fail in accept(), errno : %d, %s\n", errno, strerror(errno)); continue; } printf("new client from %s:%d\n", inet_ntoa(cliaddr.sin_addr), ntohs(cliaddr.sin_port)); while (1) { memset(buff, 0, sizeof(buff)); flag = recv(clientfd, buff, BUFFSIZE - 1, 0); if (flag == 0) { printf("peer shutdown\n"); break; } else if (flag == -1) { if (errno == EAGAIN) continue; else { printf("fail in recv()\n"); break; } } printf("\nrecv data: %s\n", buff); if (send(clientfd, buff, strlen(buff) + 1, 0) == -1) break; } close(clientfd); } end: if (listenfd) close(listenfd); return 0; }

    客户端程序

    #include <stdlib.h> #include <stdio.h> #include <string.h> #include <unistd.h> #include <errno.h> #include <arpa/inet.h> #define MAX_BUFF_SIZE 1024 int main(int argc, char **argv) { int flag; int clientfd; int reuse = 1; int addrlen; char buff[MAX_BUFF_SIZE]; struct sockaddr_in addr; addrlen = sizeof(struct sockaddr_in); if (argc < 2) { printf("Usage: %s ip port\n", argv[0]); goto end; } memset(&addr, 0, addrlen); addr.sin_family = AF_INET; addr.sin_port = htons(atoi(argv[2])); addr.sin_addr.s_addr = inet_addr(argv[1]); clientfd = socket(AF_INET, SOCK_STREAM, 0); if (clientfd == -1) { printf("fail in socket(), errno : %d, %s\n", errno, strerror(errno)); goto end; } if (setsockopt(clientfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) == -1) { printf("fail in setsockopt(), errno : %d, %s\n", errno, strerror(errno)); goto end; } if (connect(clientfd, (const struct sockaddr *)&addr, addrlen) == -1) { printf("fail in connect(), errno : %d, %s\n", errno, strerror(errno)); goto end; } while (1) { printf("\nplease input data:\n"); memset(&buff, 0, sizeof(buff)); fflush(stdin); scanf("%s", buff); printf("send date ...\n"); if (send(clientfd, buff, strlen(buff), 0) == -1) { printf("fail in send(), errno : %d, %s\n", errno, strerror(errno)); goto end; } printf("reve data ...\n"); memset(buff, 0, sizeof(buff)); flag = recv(clientfd, buff, sizeof(buff) - 1, 0); if (flag == -1) { printf("fail in recv()\n"); goto end; } else if (flag == 0) { printf("peer shutdown\n"); goto end; } else { printf("recv data:\n%s\n", buff); } } end: if (clientfd) close(clientfd); return 0; }
    转载请注明原文地址: https://ju.6miu.com/read-670724.html

    最新回复(0)