Linux网络编程——tcp实例

来源:互联网 发布:csgo loss网络优化 编辑:程序博客网 时间:2024/05/19 00:17

题目

1、通过TCP协议实现多个client端可以并发连接到server,client可获得server指定目录下的文件列表。

/* * client.c * *  Created on: 2016年11月3日 *      Author: Administrator */#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <errno.h>#include <string.h>#include <pthread.h>#include <sys/socket.h>#include <arpa/inet.h>#include <signal.h>#include <sys/types.h>#define BUFSIZE 10240int socket_connect(const char*hostname, int port){    int client_st = socket(AF_INET, SOCK_STREAM, 0);    if (client_st == -1)    {        printf("socket failed %s\n", strerror(errno));        return -1;    }    struct sockaddr_in addr;    memset(&addr, 0, sizeof(addr));    addr.sin_family = AF_INET;    addr.sin_port = htons(port);    addr.sin_addr.s_addr = inet_addr(hostname);    if (connect(client_st, (struct sockaddr*) &addr, sizeof(addr)) == -1)    {        printf("connect failed %s\n", strerror(errno));        return -1;    } else    {        printf("connect to %s:%d\n", hostname, port);        return client_st;    }}int socket_send_dir(int client_st, const char *dir){    int rc = send(client_st, dir, strlen(dir), 0);    if (rc <= 0)    {        printf("send failed %s\n", strerror(errno));        return rc;    }    char *buf = malloc(BUFSIZE);    memset(buf, 0, BUFSIZE);    rc = recv(client_st, buf, BUFSIZE, 0);    if (rc <= 0)    {        printf("recv failed %s\n", strerror(errno));        return rc;    }else    {        printf("%s\n", buf);//如果接收到来自server端的数据,将数据打印到屏幕    }    free(buf);    return rc;}int main(int arg, char*args[]){    if (arg < 3)    {        printf("usage:client hostname port\n");        return 0;    }    int iport = atoi(args[2]);    if (iport == 0)    {        printf("port %d is invaild\n", iport);        return 0;    }    int client_st = socket_connect(args[1], iport);    if (client_st == -1)    {        printf("socket_connect failed\n");        return 0;    }    char buf[200];    while (1)    {        memset(buf, 0, sizeof(buf));        read(STDIN_FILENO, buf, sizeof(buf));        if (strncmp(buf, "exit",4) == 0)            break;        buf[strlen(buf) - 1] = 0;        if (strlen(buf) == 0)            continue;        if (socket_send_dir(client_st, buf) <= 0)            break;    }    close(client_st);    return EXIT_SUCCESS;}
/* ============================================================================ Name        : CS-opendir.c Author      : Allen Version     : Copyright   : Your copyright notice Description : Hello World in C, Ansi-style ============================================================================ */#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <errno.h>#include <string.h>#include <sys/epoll.h>#include <sys/socket.h>#include <arpa/inet.h>#include <signal.h>#include <sys/types.h>#include <sys/types.h>#include <dirent.h>#include <fcntl.h>#define BUFSIZE 10240int socket_create(int port){    int st=socket(AF_INET,SOCK_STREAM,0);    int on = 1;    if (setsockopt(st, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1)    {        printf("setsockopt failed %s\n", strerror(errno));        return 0;    }    struct sockaddr_in server_addr;    memset(&server_addr, 0, sizeof(server_addr));    server_addr.sin_family = AF_INET;    server_addr.sin_port = htons(port);    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);    if ((bind(st, (struct sockaddr*) &server_addr, sizeof(server_addr))) == -1)    {        printf("bind failed %s\n", strerror(errno));        return -1;    }    if ((listen(st, 20)) == -1)    {        printf("listen failed %s\n", strerror(errno));        return -1;    }    return st;}int socket_accept(int listen_st){    struct sockaddr_in client_addr;    socklen_t len = sizeof(client_addr);    memset(&client_addr, 0, sizeof(client_addr));    int client_st = accept(listen_st, (struct sockaddr*) &client_addr, &len);    if (client_st == -1)    {        printf("accpet failed %s\n", strerror(errno));        return -1;    } else    {        printf("accept by %s\n", inet_ntoa(client_addr.sin_addr));    }    return client_st;}void getdir(const char*dirname, char*buf){    DIR *dp;    dp = opendir(dirname);    if (dp == NULL)    {        printf("opendir failed %s\n", strerror(errno));        return;    }    struct dirent *dirp;    char tmp[200];    while ((dirp = readdir(dp)) != NULL)    {        memset(tmp, 0, sizeof(tmp));        sprintf(tmp, "%s ", dirp->d_name);        strcat(buf, tmp);    }    closedir(dp);    return;}int socket_recv(int client_st){    char recvbuf[200];    memset(recvbuf, 0, sizeof(recvbuf));    char *sendbuf = malloc(BUFSIZE);    memset(sendbuf, 0, BUFSIZE);    int rc = recv(client_st, recvbuf, sizeof(recvbuf), 0);    printf("收到客户端的消息是:%s\n", recvbuf);    if (rc <= 0)    {        printf("recv failed %s\n", strerror(errno));    } else    {        getdir(recvbuf, sendbuf);        rc = send(client_st, sendbuf, strlen(sendbuf), 0);        if (rc <= 0)        {            printf("send failed %s\n", strerror(errno));        }    }    free(sendbuf);    //close(client_st);    return rc;}int setnonblocking(int st) //将socket设置为非阻塞{    int opts = fcntl(st, F_GETFL);    if (opts < 0)    {        printf("fcntl failed %s\n", strerror(errno));        return 0;    }    opts = opts | O_NONBLOCK;    if (fcntl(st, F_SETFL, opts) < 0)    {        printf("fcntl failed %s\n", strerror(errno));        return 0;    }    return 1;}void run(int port){    int listen_st = socket_create(port);    setnonblocking(listen_st);    struct epoll_event ev, events[200];    int epfd = epoll_create(200);    ev.data.fd = listen_st;    ev.events = EPOLLIN | EPOLLERR | EPOLLHUP;    epoll_ctl(epfd, EPOLL_CTL_ADD, listen_st, &ev);    int st;    while (1)    {        int nfds = epoll_wait(epfd, events, 200, -1);        if (nfds == -1)        {            printf("epoll_wait failed %s\n", strerror(errno));            break;        }        int i = 0;        for (; i < nfds; i++)        {            if (events[i].data.fd < 0)                continue;            if (events[i].data.fd == listen_st)            {                st = socket_accept(listen_st);                if (st > 0)                {                    setnonblocking(st);                    ev.data.fd = st;                    ev.events = EPOLLIN | EPOLLERR | EPOLLHUP;                    epoll_ctl(epfd, EPOLL_CTL_ADD, st, &ev);                    continue;                }            }            if (events[i].events & EPOLLIN)            {                st = events[i].data.fd;                if (socket_recv(st) <= 0)                {                    close(st);                    events[i].data.fd = -1;                }            }            if (events[i].events & EPOLLERR)            {                st = events[i].data.fd;                close(st);                events[i].data.fd = -1;            }            if (events[i].events & EPOLLHUP)            {                st = events[i].data.fd;                close(st);                events[i].data.fd = -1;            }        }    }    close(epfd);}int main(int arg, char*args[]){    if (arg < 2) //如果没有参数,main函数退出    {        printf("usage:server port\n");        return EXIT_SUCCESS;    }    int iport = atoi(args[1]); //将第一个参数转化为端口号    if (iport == 0)    {        printf("port %d is invalid\n", iport);        return EXIT_SUCCESS;    }    run(iport);    return EXIT_SUCCESS;}
.SUFFIXES: .c .oCC=gccSRCS1=server.cSRCS2=client.cOBJS1=$(SRCS1:.c=.o)OBJS2=$(SRCS2:.c=.o)EXEC1=serverEXEC2=clientall: $(OBJS1) $(OBJS2)    $(CC) -o $(EXEC1) $(OBJS1)    $(CC) -o $(EXEC2) $(OBJS2)    @echo '-------------ok--------------'.c.o:     $(CC) -Wall -g -o $@ -c $<clean:    rm -f $(OBJS1) $(OBJS2)    rm -f core*

运行结果

server
这里写图片描述
client1
这里写图片描述
client2
这里写图片描述

今天没时间为代码注释啦,改天补齐.

0 0