11月27日作业

1.select搭建TCP服务器

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define IP "192.168.8.190"
#define PROT 7777
#define ERR(err)                                   \
    do                                             \
    {                                              \
        fprintf(stderr, "errline:%d\n", __LINE__); \
        perror(err);                               \
    } while (0)
int main(int argc, const char *argv)
{
    //创建套接字
    int fd = socket(AF_INET, SOCK_STREAM, 0);
    if (fd < 0)
    {
        ERR("socket");
        return -1;
    }
    //允许端口快速重用
    int reuse = 1;
    if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0)
    {
        ERR("setsockopt");
        return -1;
    }
    //绑定套接字
    struct sockaddr_in sim, add; //这个是使用的真实的结构体 bind函数中的结构体只是为了防止报警告
    sim.sin_family = AF_INET;
    sim.sin_addr.s_addr = inet_addr(IP);
    sim.sin_port = htons(PROT);
    if (bind(fd, (struct sockaddr *)&sim, sizeof(sim)) < 0)
    {
        ERR("bind");
        return -1;
    }
    //设置监听
    if (listen(fd, 128) < 0)
    {
        ERR("listen");
        return -1;
    }
    int fs = 0;
    //创建一个集合
    fd_set readfds, tempfds;
    //初始化
    FD_ZERO(&readfds);
    FD_ZERO(&tempfds);
    //将文件描述符添加进去
    FD_SET(0, &readfds);
    FD_SET(fd, &readfds);
    //储存添加的最大的文件描述符
    int max = fd;
    int temps; //
    char str[128] = "";
    char rec[128] = "";
    ssize_t res = 0;
    socklen_t addrlen = sizeof(add);
    while (1)
    {
        tempfds = readfds;
        if (select(max + 1, &tempfds, NULL, NULL, NULL) < 0)
        {
            ERR("select");
            return -1;
        }
        for (int i = 0; i < max + 1; i++)
        {
            if (FD_ISSET(i, &tempfds) == 0)
            {
                continue; //如果集合中没有对应的,继续找
            }
            if (0 == i)
            {
                //如果等于0 就是fgets
                fgets(str,sizeof(str),stdin);
                str[strlen(str)-1]=0;
                printf("输入的:");
            }
            else if (fd == i)
            {
                //如果等于fd,代表accept
                printf("waiting......\n");
                fs = accept(fd, (struct sockaddr *)&add, &addrlen); // fd是用于accept的如果想打印数据还需要新的文件描述符,发送数据用的是fs
                if (fs < 0)
                {
                    ERR("accept");
                    return -1;
                }
                printf("客户端连接\n");
                FD_SET(fs,&readfds);
                max = fd>fs?fd:fs;//更新最大值
            }
            else
            {
                //剩下的就是发送的接收变量
                bzero(rec,sizeof(rec));
                res = recv(i,rec,sizeof(rec),0);
                if(res<0)
                {
                    ERR("recv");
                }
                else if(0 == res)
                {
                    printf("客户端断开连接\n");
                    //需要处理断开连接后的文件描述符
                    close(i);//关闭
                    FD_CLR(i,&readfds);//在集合中删除
                    //删除之后出现最大值的问题,如果删除的是最大的那个需要找到下一个最大的值
                    for(int j=max;j>0;j--)
                    {
                        if(FD_ISSET(j,&readfds))
                        {
                            max = j;
                            break;
                        }
                    }
                }
                else
                {
                    printf("%s\n",rec);
                }
            }
        }
    }
    //获取连接成功的套接字,在所有连接的队列头中选一个连接,生成新的文件描述符用于通信
    //接收recv
    //IP地址记录用链表实现
    if (close(fd) || close(fs))
    {
        ERR("close");
        return -1;
    }
    return 0;
}

2.select搭建TCP客户端

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define IP "192.168.8.190"
#define PORT 7777
#define ERR(err)                                   \
    do                                             \
    {                                              \
        fprintf(stderr, "errline:%d\n", __LINE__); \
        perror(err);                               \
    } while (0)
int main(int argc, const char *argv[])
{
    int fd = socket(AF_INET, SOCK_STREAM, 0);
    if (fd < 0)
    {
        ERR("socket");
        return -1;
    }
    struct sockaddr_in add;
    add.sin_family = AF_INET;
    add.sin_port = htons(PORT);
    add.sin_addr.s_addr = inet_addr(IP);
    if (connect(fd, (struct sockaddr *)&add, sizeof(add)) < 0)
    {
        ERR("connect");
        return -1;
    }
    fd_set readfds, tempfds;
    FD_ZERO(&readfds);
    FD_ZERO(&tempfds);
    FD_SET(0, &readfds);
    FD_SET(fd, &readfds);
    int max = fd;
    char sendbuff[128] = "";
    char recvbuff[128] = "";
    while (1)
    {
        tempfds = readfds;
        if(select(max+1,&tempfds,NULL,NULL,NULL)<0)
        {
            ERR("select");
            return -1;
        }
        for(int i=0;i<max+1;i++)
        {
            if(0 == FD_ISSET(i,&tempfds))
            {
                continue;
            }
            if(0 == i)
            {
                bzero(sendbuff,sizeof(sendbuff));
                fgets(sendbuff,sizeof(sendbuff),stdin);
                sendbuff[strlen(sendbuff)-1];
                if(send(fd,sendbuff,sizeof(sendbuff),0)<0)
                {
                    ERR("send");
                    return -1;
                }

            }
            else if(fd == i)
            {
                bzero(recvbuff,sizeof(recvbuff));
                if(recv(fd,recvbuff,sizeof(recvbuff),0)<0)
                {
                    ERR("recv");
                    return -1;
                }
                printf("%s\n",recvbuff);
            }
        }
    }
    close(fd);
    return 0;
}

3.poll搭建TCP客户端

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define IP "192.168.8.190"
#define PORT 7777
#define ERR(err)                                   \
    do                                             \
    {                                              \
        fprintf(stderr, "errline:%d\n", __LINE__); \
        perror(err);                               \
    } while (0)
int main(int argc, const char *argv)
{
    //创建套接字
    int fd = socket(AF_INET, SOCK_STREAM, 0);
    if (fd < 0)
    {
        ERR("socket");
        return -1;
    }
    struct sockaddr_in add;
    add.sin_family = AF_INET;
    add.sin_port = htons(PORT);
    add.sin_addr.s_addr = inet_addr(IP);
    if (connect(fd, (struct sockaddr *)&add, sizeof(add)) < 0)
    {
        ERR("connect");
        return -1;
    }
    //创建一个事件集合
    struct pollfd akg[2];
    akg[0].fd = 0;          //用于监测stdin即终端输入
    akg[0].events = POLLIN; //监测读事件,需要手动添加
    akg[1].fd = fd;         //监测套接字文件描述符
    akg[1].events = POLLIN; //监测读事件
    char sendbuff[128] = "";
    char recvbuff[128] = "";
    ssize_t res = 0;
    while (1)
    {
        int pds = poll(akg, 2, -1);
        if (pds < 0)
        {
            ERR("poll");
            return -1;
        }
        else if (0 == pds)
        {
            printf("服务器异常\n");
            return -1;
        }
        if (akg[0].revents & POLLIN)
        {
            bzero(sendbuff,sizeof(sendbuff));
            fgets(sendbuff,sizeof(sendbuff),stdin);
            sendbuff[strlen(sendbuff)-1];
            if(send(fd,sendbuff,sizeof(sendbuff),0)<0)
            {
                ERR("send");
                return -1;
            }
        }
        if(akg[1].events&POLLIN)
        {
            bzero(recvbuff,sizeof(recvbuff));
            res = recv(fd,recvbuff,sizeof(recvbuff),0);
            if(res<0)
            {
                ERR("recv");
                return -1;
            }
            else if(0 == res)
            {
                printf("服务器断开连接\n");
                break;
            }
            printf("%s\n",recvbuff);
        }
    }
    if(close(fd)<0)
    {
        ERR("close");
        return -1;
    }
}

4.基于TCP的文件服务器以及客户端
服务器:
fun.h

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define N 64
#define M 64
#define LICENCE "201810"
#define IP "192.168.8.190"
#define PORT 8888
#define ERR(err)                                   \
    do                                             \
    {                                              \
        fprintf(stderr, "errline:%d\n", __LINE__); \
        perror(err);                               \
    } while (0)
typedef struct mas
{
    int fs;
    char recvbuff[128];     //储存接收的数据判断请求
} info;
int init();
void *callback(void *arg);
int UserSignIn(int fd);
int Register(int fd); //用户注册
int File_Info(int fd,char *fox);
int RecvFile(int fd, char *fox);
int SendFile(int fd, char *recvbuff);
int Exit(int fd);

func.c

#include "func.h"
int init()
{
    int fd = socket(AF_INET, SOCK_STREAM, 0);
    if (fd < 0)
    {
        ERR("socket");
        return -1;
    }
    //允许端口快速重用
    int value;
    if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &value, sizeof(value)) < 0)
    {
        ERR("setsockopt");
        return -1;
    }
    struct sockaddr_in add;
    add.sin_family = AF_INET;
    add.sin_addr.s_addr = inet_addr(IP);
    add.sin_port = htons(PORT);
    if (bind(fd, (struct sockaddr *)&add, sizeof(add)) < 0)
    {
        ERR("bind");
        return -1;
    }
    if (listen(fd, 128) < 0)
    {
        ERR("listen");
        return -1;
    }
    return fd;
}
void *callback(void *arg)
{
    pthread_detach(pthread_self());
    char recvbuff[128] = "";
    short temp = 0;
    ssize_t res = 0;
    int flag = 1;
    int fd = ((info *)arg)->fs; //用于通信
    while (flag)
    {
        res = recv(fd, recvbuff, sizeof(recvbuff), 0);
        if (0 == res)
        {
            printf("客户端退出\n");
            return NULL;
        }
        temp = ntohs(*(short *)recvbuff);
        switch (temp)
        {
        case 1:
            SendFile(fd, recvbuff);
            break; //发送文件
        case 2:
            RecvFile(fd, recvbuff);
            break; //接收文件
        case 3:
            Register(fd);
            break; //注册
        case 4:
            File_Info(fd, recvbuff);
            break; //打印目录信息
        case 5:
            close(fd);
            flag = 0;
            pthread_exit(NULL); //退出
        case 6:
            UserSignIn(fd);
            break;
        default:
            break;
        }
    }
}
int UserSignIn(int fd) //用户登录
{
    printf("line :%d", __LINE__);
    char uname[N] = "";
    char passwd[M] = "";
    char inputname[N] = "";
    char inputpasswd[M] = "";
    char recvbuff[M] = "";
    FILE *fp = fopen("/home/yyh/C/FILESERVER/key/key.txt", "r");
    if (NULL == fp)
    {
        ERR("fp");
        return -1;
    }
    if (recv(fd, recvbuff, sizeof(recvbuff), 0) < 0)
    {
        ERR("recv");
        return -1;
    }
    char *p = recvbuff;
    int i = 0;
    while (*p != ' ')
    {
        inputname[i] = *p;
        i++;
        p += 1;
    }
    strcpy(inputpasswd, p + 1);
    while (1)
    {
        if (EOF == fscanf(fp, "%s %s", uname, passwd))
        {
            if (0 == errno)
            {
                if (send(fd, "账户或者密码错误\n", sizeof("账户或者密码错误\n"), 0) < 0)
                {
                    ERR("send");
                    return -1;
                }
                bzero(recvbuff, sizeof(recvbuff));
                continue;
            }
            else
            {
                ERR("fscanf");
                return -1;
            }
        }
        if (!strcmp(inputname, uname))
        {
            if (!strcmp(inputpasswd, passwd))
            {
                if (send(fd, "登录成功", sizeof("登录成功"), 0) < 0)
                {
                    ERR("send");
                    return -1;
                }
                break;
            }
            else
            {
                if (send(fd, "账户或者密码错误", sizeof("账户或者密码错误"), 0) < 0)
                {
                    ERR("send");
                    return -1;
                }
                bzero(recvbuff, sizeof(recvbuff));
                continue;
            }
        }
    }
    if (fclose(fp) < 0)
    {
        ERR("fclose");
        return -1;
    }
}
int Register(int fd) //用户注册
{
    char permit[128] = "";
    char name[N] = "";       //储存要注册的姓名
    char passwd[M] = "";     //储存要注册的密码
    char recvbuff[128] = ""; //储存接受到的信息
    ssize_t res = recv(fd, permit, sizeof(permit), 0);
    if (res < 0)
    {
        ERR("recv");
        return -1;
    }
    else if (0 == res)
    {
        if (send(fd, "传输中断,请检查网络后重试\n", sizeof("传输中断,请检查网络后重试\n"), 0) < 0)
        {
            ERR("send");
            return -1;
        }
        return -1;
    }
    if (!strcmp(LICENCE, permit))
    {
        if (send(fd, "se\n", sizeof("se\n"), 0) < 0)
        {
            ERR("send");
            return -1;
        }
    }
    else
    {
        if (send(fd, "err", sizeof("err"), 0) < 0)
        {
            ERR("send");
            return -1;
        }
        return -1;
    }
    FILE *fp = fopen("/home/yyh/C/FILESERVER/key/key.txt", "a");
    if (NULL == fp)
    {
        ERR("fopen");
        return -1;
    }
    bzero(name, sizeof(name));
    bzero(passwd, sizeof(passwd));
    if (recv(fd, recvbuff, sizeof(recvbuff), 0) < 0)
    {
        ERR("recv");
        return -1;
    }
    char *p = recvbuff;
    int i = 0;
    while (*p != ' ')
    {
        name[i] = *p;
        i++;
        p += 1;
    }
    strcpy(passwd, p + 1);
    if (fprintf(fp, "%s %s\n", name, passwd) < 0)
    {
        ERR("fprintf");
        return -1;
    }
    printf("%s %s\n", name, passwd);
    printf("注册成功\n");
    if (fclose(fp) < 0)
    {
        ERR("fclose");
        return -1;
    }
}
int File_Info(int fd, char *fox)
{
    char sendbuff[300] = "";
    char pathname[64] = "";
    char *p = fox + 2;
    int i = 0;
    while (*p) //获得数据包中的文件名称
    {
        pathname[i] = *p;
        p += 1;
        i++;
    }
    // FILE *fp = fopen("./file)
    DIR *dir = opendir(pathname);
    if (dir < 0)
    {
        ERR("open");
        return -1;
    }
    struct dirent *dire;
    while (1)
    {
        dire = readdir(dir);
        if (NULL == dire)
        {
            if (0 == errno)
            {
                printf("读取完毕\n");
                break;
            }
            else
            {
                ERR("readdir");
                return -1;
            }
        }
        if (!strcmp(dire->d_name, ".") || !strcmp(dire->d_name, ".."))
        {
            continue;
        }
        int num = sprintf(sendbuff, "%s%c", dire->d_name, ' ');
        printf("%s", sendbuff);
        if (send(fd, sendbuff, strlen(sendbuff), 0) < 0)
        {
            ERR("send");
            return -1;
        }
    }
    if (closedir(dir) < 0)
    {
        ERR("closedir");
        return -1;
    }
}
int RecvFile(int fd, char *fox)
{
    char filename[128] = "";
    char buff[516] = "";
    char *p = fox + 2;
    int i = 0;
    while (*p) //获得数据包中的文件名称
    {
        filename[i] = *p;
        p += 1;
        i++;
    }
    ssize_t res;
    int fs = open("./1.c", O_RDWR | O_CREAT | O_TRUNC, 0777);
    if (fs < 0)
    {
        ERR("open");
        return -1;
    }
    while (1)
    {
        res = recv(fd, buff, sizeof(buff), 0);
        if (res < 0)
        {
            ERR("recv");
            return -1;
        }
        else if (0 == res)
        {
            printf("客户端异常\n");
            return -1;
        }
        if (write(fs, buff, res) < 0)
        {
            ERR("write");
            return -1;
        }
        if (res < 516)
        {
            printf("接收完毕\n");
            break;
        }
    }
    close(fd);
}
int SendFile(int fd, char *recvbuff)
{
    char name[64] = ""; //储存名称
    char *p = recvbuff + 2;
    int i = 0;
    char sendbuff[516] = "";
    while (*p) //获得数据包中的文件名称
    {
        name[i] = *p;
        p += 1;
        i++;
    }
    ssize_t res;
    int fs = open(name, O_RDONLY);
    if (fs < 0)
    {
        printf("没有找到文件\n");
        ERR("open");
        return -1;
    }
    while (1)
    {
        bzero(sendbuff, sizeof(sendbuff));
        res = read(fs, sendbuff, sizeof(sendbuff));
        if (res < 0)
        {
            ERR("read");
            return -1;
        }
        else if (0 == res)
        {
            printf("文件发送完毕\n");
            break;
        }
        if (send(fd, sendbuff, res, 0) < 0)
        {
            ERR("send");
            break;
        }
    }
    close(fd);
}

main.c

#include "func.h"
int main(int argc,const char *argv[])
{
    info rng;
    int fd = init();
    int fs;                 //用于通信
    struct sockaddr_in edg; //存储接收方信息的结构体
    socklen_t size = sizeof(edg);
    while (1)
    {
        fs = accept(fd, (struct sockaddr *)&edg, &size); // accept会提前指定。 每接入一个就会开两个线程以及一个临时端口用于通信
        if (fs < 0)
        {
            ERR("accept");
            return -1;
        }
        printf("IP:[%s]Prot:[%d]连接成功\n",inet_ntoa(edg.sin_addr),ntohs(edg.sin_port));
        rng.fs = fs;
        pthread_t thread;
        if (pthread_create(&thread, NULL, callback, (void *)&rng) != 0)
        {
            ERR("pthread_create");
            return -1;
        }
    }
    if (close(fd) < 0 || close(fs)<0)
    {
        ERR("close");
        return -1;
    }
}

Makefile

all:x
x:func.o
x:main.o
	gcc func.o main.o -o x
func.o:func.c
main.o:main.c
	gcc -c func.c -o func.o
	gcc -c main.c -o main.o

clean:
	rm func.o main.o x

客户端
func.h

#define IP "192.168.8.190"
#define PORT 8888
#define N 48 //上传文件路径数组的大小
#define M 516 //用于发送的数组大小
#define ERR(err)                                   \
    do                                             \
    {                                              \
        fprintf(stderr, "errline:%d\n", __LINE__); \
        perror(err);                               \
    } while (0)
int LogIn(int fd);
int Init();
int UpLode(int fd);
int DownLode(int fd);
int ShowDir(int fd);
int Register(int fd);
int Exits(int fd);

func.c

#include "func.h"
int LogIn(int fd)
{
    ssize_t res = 0;
    char sendstr[128] = "";
    char sendstr1[64] = "";
    char sendstr2[64] = "";
    char recvstr[128] = "";
    char request[24] = "";
    int comd = sprintf(request,"%c%c%c",0,6,0);
    if(send(fd,request,comd,0)<0)
    {
        ERR("send");
        return -1;
    }
    while (1)
    {
        // send
        bzero(sendstr, sizeof(sendstr));
        printf("name:");
        scanf("%s", sendstr1);
        while (getchar() != '\n');
        printf("passwd:");
        scanf("%s", sendstr2);
        while (getchar() != '\n');
        sprintf(sendstr, "%s %s", sendstr1, sendstr2);
        printf("line:%d\n",__LINE__);
        if (send(fd, sendstr, sizeof(sendstr), 0) < 0)
        {
            ERR("send");
            return -1;
        }
        printf("line:%d\n",__LINE__);
        // recv
        bzero(recvstr, sizeof(recvstr));
        res = recv(fd, recvstr, sizeof(recvstr), 0);
        if (res < 0)
        {
            ERR("recv");
            return -1;
        }
        else if (0 == res)
        {
            printf("服务器异常\n");
            break;
        }
        if (!strcmp(recvstr, "登录成功"))
        {
            printf("登录成功\n");
            break;
        }
        else
        {
            printf("登录失败\n");
            exit(0);
        }
    }
}
//上传文件
int UpLode(int fd) //参数为套接字的文件描述符
{
    ssize_t res = 0;
    char request[M] = "";
    char pathname[N] = "";
    char sendbuff[M] = "";
    char recvbuff[N] = "";
    printf("请输入要上传的文件路径:");
    fflush(stdout);
    fgets(pathname, sizeof(pathname), stdin);
    pathname[strlen(pathname) - 1] = 0;
    int fp = open(pathname, O_RDONLY);
    if (fp < 0)
    {
        ERR("open");
        return -1;
    }
    //发送请求
    int size = sprintf(request, "%c%c%s%c", 0, 2, pathname, 0); //
    if (send(fd, request, size, 0) < 0)
    {
        ERR("send");
        return -1;
    }
    while (1)
    {
        bzero(sendbuff, sizeof(sendbuff));
        res = read(fp, sendbuff, 516);
        if (res < 0)
        {
            ERR("read");
            return -1;
        }
        else if (0 == res)
        {
            printf("上传完毕\n");
            break;
        }
        if (send(fd, sendbuff, res, 0) < 0)
        {
            ERR("send");
            return -1;
        }
    }
}
//注册
int Register(int fd)
{
    char permit[24] = "";
    char recvbuff[128] = "";
    char name[N] = "";   //储存要注册的姓名
    char passwd[N] = ""; //储存要注册的密码
    char sendbuff[500] = "";
    char request[24] = "";
    int sizes = sprintf(request, "%c%c%c", 0, 3, 0);
    if (send(fd, request, sizes, 0) < 0)
    {
        ERR("send");
        return -1;
    }
    printf("请输入管理员给的许可证:");
    fgets(permit, sizeof(permit), stdin);
    permit[strlen(permit) - 1] = 0;
    if (send(fd, permit, sizeof(permit), 0) < 0)
    {
        ERR("send");
        return -1;
    }
    if (recv(fd, recvbuff, sizeof(recvbuff), 0) < 0)
    {
        ERR("recv");
        return -1;
    }
    if (!strcmp(recvbuff, "err"))
    {
        printf("许可证错误,请联系管理员后重试\n");
        return -1;
    }
    else if (!strcmp(recvbuff, "se"))
    {
        printf("验证通过\n");
    }
    printf("请输入用户名:");
    fgets(name, sizeof(name), stdin);
    name[strlen(name) - 1] = 0;
    printf("请输入密码:");
    fgets(passwd, sizeof(passwd), stdin);
    passwd[strlen(passwd) - 1] = 0;
    int size = sprintf(sendbuff, "%s %s", name, passwd);
    printf("%s\n", sendbuff);
    if (send(fd, sendbuff, sizeof(sendbuff), 0) < 0)
    {
        ERR("send");
        return -1;
    }
}
//下载文件
int DownLode(int fd) //参数为套接字文件描述符
{
    //先发请求
    ssize_t res;
    char filename[N] = "";
    char requset[M] = "";
    char recvbuff[M] = "";
    printf("请输入要下载的文件名或者路径:");
    fflush(stdout);
    fgets(filename, sizeof(filename), stdin);
    filename[strlen(filename) - 1] = 0;
    int size = sprintf(requset, "%c%c%s%c", 0, 1, filename, 0);
    if (send(fd, requset, size, 0) < 0)
    {
        ERR("send");
        return -1;
    }
    int fk = open("./1.png", O_RDWR | O_CREAT | O_TRUNC, 0777);
    if (fk < 0)
    {
        ERR("open");
        return -1;
    }
    //服务器发来一个数据包
    while (1)
    {
        res = recv(fd, recvbuff, sizeof(recvbuff), 0);
        if (res < 0)
        {
            ERR("res");
            return -1;
        }
        else if (0 == res)
        {
            printf("传输异常\n");
            return -1;
        }
        if (write(fk, recvbuff, res) < 0) // write这里全部都需要检查一遍,还有网络字节序和本机字节序转换
        {
            ERR("write");
            return -1;
        }
        if (res < M)
        {
            printf("传输完毕\n");
            break;
        }
    }
}
//查看目录
int ShowDir(int fd) //参数为套接字文件描述符
{
    ssize_t res, fds = 0;
    char filedir[N] = "";
    char request[M] = "";
    char recvbuff[N] = "";
    printf("请输入要打开的目录:");
    fflush(stdout);
    fgets(filedir, sizeof(filedir), stdin);
    filedir[strlen(filedir) - 1] = 0;
    //发送请求
    int size = sprintf(request, "%c%c%s%c", 0, 4, filedir, 0);
    if (send(fd, request, sizeof(request), 0) < 0)
    {
        ERR("send");
        return -1;
    }
    //接收发过来的目录文件
    while (1)
    {
        res = recv(fd, recvbuff, sizeof(recvbuff), 0);
        if (res < 0)
        {
            ERR("recv");
            return -1;
        }
        else if (0 == res)
        {
            printf("服务器断开连接\n");
            return -1;
        }
        printf("%s\n", recvbuff); //直接打印出来
        if (res < N)
        {
            printf("接收完毕\n");
            break;
        }
    }
}
//退出程序
int Exits(int fd)
{
    char buff[10] = "";
    bzero(buff, sizeof(buff));
    *(short *)buff = htons(5);
    if (send(fd, buff, sizeof(buff), 0) < 0)
    {
        ERR("send");
        return -1;
    }

}

main.c

#include "func.h"
int main(int argc, const char *argv[])
{
    int flag = 0;
    struct sockaddr_in mss;
    int fd = socket(AF_INET, SOCK_STREAM, 0);
    if (fd < 0)
    {
        ERR("socket");
        return -1;
    }
    mss.sin_addr.s_addr = inet_addr(IP);
    mss.sin_family = AF_INET;
    mss.sin_port = ntohs(PORT);
    if (connect(fd, (struct sockaddr *)&mss, sizeof(mss)) < 0)
    {
        ERR("connect");
        return -1;
    }
    LogIn(fd);//连接成功先登录
    while (1)
    {
        printf("**************************************************\n");
        printf("*****1.下载 2.上传  3.注册 4.打印目录信息 5.退出*****\n");
        printf("**************************************************\n");
        scanf("%d", &flag);
        while (getchar() != '\n')
            ;
        switch (flag)
        {
        case 1:
            DownLode(fd);
            break;
        case 2:
            UpLode(fd);
            break;
        case 3:
            Register(fd);
            break; //注册
        case 4:
            ShowDir(fd);
            break;
        case 5:
            Exits(fd); //退出
            break;
        default:
            break;
        }
    }
    close(fd);
    return 0;
}

Makefile

all:x
x:func.o
x:main.o
	gcc func.o main.o -o x
func.o:func.c
main.o:main.c
	gcc -c func.c -o func.o
	gcc -c main.c -o main.o

clean:
	rm func.o main.o x

你可能感兴趣的:(网络,tcp/ip,网络协议)