查看上传下载

chatClient.c

#include "chatClient.h"

Head *g_pHead = NULL;
void sendDataToServer(int sockfd, ChatPDU *pChatPDU)
{
    if (NULL == pChatPDU)
    {
        return;
    }
    int ret = 0;
    int iLeft = pChatPDU->iChatPDULen;
    int iSend = 0;
    ret = write(sockfd, pChatPDU, iLeft);
    if (-1 == ret)
    {
        PRINT_ERROR("send");
        return;
    }
    iLeft -= ret;  //还有多少数据要发送
    iSend += ret;  //已发送的数据大小
    while (ret > 0 && iLeft)
    {
        ret = write(sockfd, (char *)pChatPDU+iSend
                    , iLeft);
        if (-1 == ret)
        {
            PRINT_ERROR("send");
            return;
        }
        iLeft -= ret;
        iSend += ret;
    }
}

ChatPDU *readDataFromServer(int sockfd)
{
    int ret = 0;
    unsigned int iPDULen = 0;
    ret = read(sockfd, &iPDULen, sizeof(int));
    if (-1 == ret)
    {
        PRINT_ERROR("recv");
        return;
    }
    ChatPDU *pChatPDU = makeChatPDU(iPDULen);
    memset(pChatPDU, 0, iPDULen);
    pChatPDU->iChatPDULen = iPDULen;
    int iLeft = iPDULen - ret;  //剩余的数据大小
    int iRecv = ret;   //已读的数据大小
    while (ret > 0 && iLeft)
    {
        ret = read(sockfd, (char*)pChatPDU+iRecv
                   , iLeft);
        if (-1 == ret)
        {
            PRINT_ERROR("recv");
            return;
        }
        iRecv += ret;
        iLeft -= ret;
    }
    return pChatPDU;
}

int makeSocket()
{
    int sockfd = 0;
    //AF_INET: ipv4
    //SOCK_STREAM: tcp/ip
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (-1 == sockfd)
    {
        PRINT_ERROR("socket");
        exit(-1);
    }
    return sockfd;
}
int connectToServer(int sockfd)
{
    struct sockaddr_in servaddr;
    //地址协议:ipv4
    servaddr.sin_family = AF_INET;
    //服务器端口
    servaddr.sin_port = htons(8668);
    //服务器ip
    servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
    bzero(&(servaddr.sin_zero), 8);
    int ret = connect(sockfd
                      , (struct sockaddr *)&servaddr
                      , sizeof(struct sockaddr));
    if (-1 == ret)
    {
        PRINT_ERROR("connect");
        exit(-1);
    }
    return ret;
}

int operateUI()
{
    printf("1,查看文件\t2,上传文件\n");
    printf("3,下载文件\t4,文件重命名\n");
    printf("ope:");
    int iOpe = 0;
    scanf("%d", &iOpe);
    if (CHAECK_INPUT(iOpe, 1, 4))
    {
        return iOpe;
    }
    return -1;
}

static void getFileListFromPDU(const ChatPDU *pChatPDU)
{
    if (NULL != pChatPDU)
    {
        int iNum = 0;
        Node *pNode = NULL;
        iNum = pChatPDU->iChatDataLen/FILE_NAME_LEN;
        int i = 0;
        for (; i < iNum; i++)
        {
            pNode = makeNode();
            memcpy(pNode->caName
                   , pChatPDU->chatData+i*FILE_NAME_LEN
                   , FILE_NAME_LEN);
            insertList(g_pHead, pNode);
        }
    }
}

static void handleAskFileList(int sockfd)
{
    destoryList(g_pHead);

    int iLen = sizeof(ChatPDU);
    ChatPDU *pChatPDU = makeChatPDU(iLen);
    if (NULL != pChatPDU)
    {
        pChatPDU->iChatPDULen = iLen;
        pChatPDU->iType = ENUM_TYPE_ASK_FILE_INFO;
        sendDataToServer(sockfd, pChatPDU);
        freePDU(pChatPDU);
        pChatPDU = NULL;

        pChatPDU = readDataFromServer(sockfd);
        getFileListFromPDU(pChatPDU);
        freePDU(pChatPDU);
        pChatPDU = NULL;

        showList(g_pHead);
    }
}

void readDataFromSTDIN(char caData[FILE_IO_MAX_LEN])
{
    memset(caData, '\0', FILE_IO_MAX_LEN);
    int ret = read(STDIN_FILENO, caData, FILE_IO_MAX_LEN);
    if (-1 == ret)
    {
        perror("read");
        return;
    }
    if ('\0' != caData[FILE_IO_MAX_LEN-1]
            && '\n' != caData[FILE_IO_MAX_LEN-1])
    {
        while ('\n' != getchar())
        {}
    }
    caData[FILE_IO_MAX_LEN-1] = '\0';
}

static void handleUploadFile(int sockfd)
{
    char caData[FILE_IO_MAX_LEN];
    // 输入时以'/'结束
    printf("请输入要上传的文件路径(以\'/\'结尾):\n");
    readDataFromSTDIN(caData);
    char caPath[64];
    memset(caPath, '\0', 64);
    sscanf(caData, "%s", caPath);
    scanFileInfo(caPath);

    printf("请输入要上传的文件名:\n");
    readDataFromSTDIN(caData);
    char caName[32] = {'\0'};
    memset(caName, '\0', 32);
    sscanf(caData, "%s", caName);

    Node *pNode = makeNode();
    initNode(pNode, caName);
    insertList(g_pHead, pNode);

    strcat(caPath, caName);
    printf("name=%s\n", caPath);

    int fd = openFile(caPath);
    int ret = -1;
    int iLen = sizeof(ChatPDU)-sizeof(int)+FILE_IO_MAX_LEN;
    ChatPDU *pChatPDU = makeChatPDU(iLen);
    pChatPDU->iChatPDULen = iLen;
    pChatPDU->iType = ENUM_TYPE_UPLOAD_FILE;
    strcpy(pChatPDU->caFileName, caName);
    while (ret = read(fd, caData, FILE_IO_MAX_LEN))
    {
        pChatPDU->iChatDataLen = ret;
        memcpy(pChatPDU->chatData, caData, ret);
        sendDataToServer(sockfd, pChatPDU);
    }
    freePDU(pChatPDU);
}

void handleDownloadFile(int sockfd)
{
    int iLen = sizeof(ChatPDU);
    ChatPDU *pChatPDU = makeChatPDU(iLen);
    if (NULL != pChatPDU)
    {
        char caData[FILE_IO_MAX_LEN];
        char caPath[64];

        pChatPDU->iChatPDULen = iLen;
        pChatPDU->iType = ENUM_TYPE_ASK_DOWNLOAD_FILE;

        showList(g_pHead);
        printf("请输入要下载的文件名:\n");
        readDataFromSTDIN(caData);
        sscanf(caData, "%s", caPath);
        strcpy(pChatPDU->caFileName, caPath);

        sendDataToServer(sockfd, pChatPDU);
        freePDU(pChatPDU);
        pChatPDU = NULL;

        unsigned int iReceivedFileSize = 0;
        // 输入时以'/'结束
        printf("请输入要保存的文件路径(以\'/\'结尾):\n");
        readDataFromSTDIN(caData);
        memset(caPath, '\0', 64);
        sscanf(caData, "%s", caPath);
        pChatPDU = readDataFromServer(sockfd);
        strcat(caPath, pChatPDU->caFileName);
        int fd = -1;
        fd = openFile(caPath);
        lseek(fd, 0, SEEK_END);
        printf("file size = %d\n", pChatPDU->iFileSize);
        while (1)
        {
            memset(caData, '\0', FILE_IO_MAX_LEN+1);
            strncpy(caData, pChatPDU->chatData, pChatPDU->iChatDataLen);
            printf("per size = %d\n", pChatPDU->iChatDataLen);

            lseek(fd, 0, SEEK_END);
            writeDataToFile(fd, caData, pChatPDU->iChatDataLen);

            iReceivedFileSize += pChatPDU->iChatDataLen;
            printf("rec=%d\n", iReceivedFileSize);
            printf("total = %d\n", pChatPDU->iFileSize);
            if (iReceivedFileSize == pChatPDU->iFileSize)
            {
                freePDU(pChatPDU);
                pChatPDU = NULL;
                break;
            }

            freePDU(pChatPDU);
            pChatPDU = NULL;

            pChatPDU = readDataFromServer(sockfd);
        }
        closeFile(fd);
        printf("文件下载完成\n");
    }
}

void interactWithServer(int sockfd)
{
    g_pHead = makeList();
    int ret = 0;
    while (1)
    {
        ret = operateUI();
        if (-1 == ret)
        {
            printf("input error\n");
            continue;
        }
        switch (ret)
        {
        case ENUM_FILE_LIST:
            handleAskFileList(sockfd);
            break;
        case ENUM_FILE_UPLOAD:
            handleUploadFile(sockfd);
            break;
        case ENUM_FILE_DOWNLOAD:
            handleDownloadFile(sockfd);
            break;
        case ENUM_FILE_RENAME:
            break;
        default:
            break;
        }
    }
}

chatClient.h

#ifndef CHAT_CLIENT_H
#define CHAT_CLIENT_H

#include <stdio.h>
#include <string.h>
/*socket() connect()  recv()*/
#include <sys/types.h> 
#include <sys/socket.h>
#include <netinet/in.h>  //struct sockaddr_in
#include <pthread.h>  //thread
#include <stdlib.h>  //malloc()
#include <unistd.h>  //read()
#if 1
#include "node.h"
#include "protocol.h"
#include "file.h"
#include "error.h"
#endif
#if 0
#include "../link/node.h"
#include "../protocol/protocol.h"
#include "../file/file.h"
#include "../error/error.h"
#endif
enum FILE_OPE
{
    ENUM_FILE_OPE_MIN = 0,
    ENUM_FILE_LIST,        //查看文件
    ENUM_FILE_UPLOAD,      //上传文件
    ENUM_FILE_DOWNLOAD,    //下载文件
    ENUM_FILE_RENAME,      //文件重命名
    ENUM_FILE_OPE_MAX = 0x0fffffff
};
#define CHAECK_INPUT(i, a, b) ((i)>=(a)&&(i<=(b)))?1:0

void sendDataToServer(int sockfd, ChatPDU *pChatPDU);
ChatPDU *readDataFromServer(int sockfd);
int makeSocket();
int connectToServer(int sockfd);
int operateUI();
void interactWithServer(int sockfd);

#endif

main(client)

#include "chatClient.h"

int main(void)
{
    int sockfd = 0;
    sockfd = makeSocket();
    connectToServer(sockfd);
    interactWithServer(sockfd);

    return 0;
}

error.c

#include "error.h"

error.h

#ifndef ERROR_H
#define ERROR_H

#include <stdio.h>
#include <string.h>
#include <errno.h>

#define PRINT_ERROR(s) printf("%s: errno=%d,err=%s\n", s, errno, strerror(errno));

#endif

file.h

#ifndef FILE_H
#define FILE_H

#include <stdio.h>
#include <string.h> //perror strerror 
#include <errno.h>  //errno
/*open()*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h> //exit()
#include <unistd.h>  //read() write()
#include "node.h"
#include "error.h"

#define FILE_IO_MAX_LEN 4096

int openFile(const char *pFileName);
void readDataFromFile(int fd, char *pBuf);
void writeDataToFile(int fd, const char *pBuf, unsigned int iLen);
void closeFile(int fd);
void scanFileIntoList(Head *pHead, const char *pDirName);
void scanFileInfo(const char *pDirName);

#endif

file.c

#include "file.h"
#include <sys/types.h>
#include <dirent.h>

int openFile(const char *pFileName)
{
    int fd = -1;
    if (NULL != pFileName)
    {
        fd = open(pFileName, O_RDWR | O_CREAT
                  , S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
        if (-1 == fd)
        {
            PRINT_ERROR("open file");
            exit(-1);
        }   
    }
    return fd;
}
void readDataFromFile(int fd, char *pBuf)
{
    if (NULL != pBuf && fd >= 0)
    {
        int ret = 0;
        int iLeft = FILE_IO_MAX_LEN;
        int iReaded = 0;
        ret = read(fd, pBuf, iLeft);
        if (-1 == ret)
        {
            PRINT_ERROR("read");
            exit(-1);
        }
        iLeft -= ret;
        iReaded += ret;
        while (ret > 0 && iLeft)
        {
            ret = read(fd, pBuf+iReaded, iLeft);
            if (-1 == ret)
            {
                PRINT_ERROR("read");
                exit(-1);
            }
            iLeft -= ret;
            iReaded += ret;
        }
    }
}
void writeDataToFile(int fd, const char *pBuf, unsigned int iLen)
{
    if (NULL != pBuf && fd >= 0)
    {
        int ret = 0;
        int iLeft = iLen;
        int iWrited = 0;
        ret = write(fd, pBuf, iLeft);
        if (-1 == ret)
        {
            PRINT_ERROR("write");
            exit(-1);
        }
        iLeft -= ret;
        iWrited += ret;
        while (ret > 0 && iLeft)
        {
            ret = write(fd, pBuf+iWrited, iLeft);
            if (-1 == ret)
            {
                PRINT_ERROR("write");
                exit(-1);
            }
            iLeft -= ret;
            iWrited += ret;
        }
    }
}
void closeFile(int fd)
{
    if (fd >= 0)
    {
        int ret = 0;
        ret = close(fd);
        if (-1 == ret)
        {
            PRINT_ERROR("close");
            exit(-1);
        }
    }
}
void scanFileIntoList(Head *pHead
                      , const char *pDirName)
{
    if (NULL == pHead)
    {
        return;
    }

    DIR *pDir = NULL;
    pDir = opendir(pDirName);  //打开目录
    if (NULL == pDir)
    {
        PRINT_ERROR("opendir");
        exit(-1);
    }
    struct dirent *pDirent = NULL;
    Node *pNode = NULL;
    //循环遍历该目录下的文件,返回某个文件的信息
    while (pDirent = readdir(pDir))  
    {
        if (0 == strcmp(".", pDirent->d_name)
            || 0 == strcmp("..", pDirent->d_name))
        {
            continue;
        }
        pNode = makeNode();

        //获得某个文件的名字并保存到节点中
        strncpy(pNode->caName, pDirent->d_name
                , FILE_NAME_LEN);
        insertList(pHead, pNode);
    }
}


void scanFileInfo(const char *pDirName)
{
    DIR *pDir = NULL;
    pDir = opendir(pDirName);  //打开目录
    if (NULL == pDir)
    {
        PRINT_ERROR("opendir");
        exit(-1);
    }
    struct dirent *pDirent = NULL;
    int i = 0;
    //循环遍历该目录下的文件,返回某个文件的信息
    while (pDirent = readdir(pDir))
    {
        if (0 == strcmp(".", pDirent->d_name)
            || 0 == strcmp("..", pDirent->d_name))
        {
            continue;
        }
        printf("%s ", pDirent->d_name);
        i++;
        if (0 == i%5)
        {
            printf("\n");
        }
    }
    printf("\n");
}

node.h

#ifndef NODE_H
#define NODE_H

#include <stdio.h>

#define FILE_NAME_LEN 32
typedef struct Node
{
    char caName[FILE_NAME_LEN];
    struct Node *pNext;
}Node;

typedef struct Head
{
    int iNum;
    Node *pFirstNode;
}Head;

Head *makeList();
Node *makeNode();
void initNode(Node *node, char *pFileName);
void insertList(Head *head, Node *node);
Node *findNode(Head *head, char *pFileName);
void deleteNode(Head *head, char *pFileName);
void showList(Head *head);
void destoryList(Head *head);
void showNode(Node *node);

#endif

node.c

#include "node.h"
#include "error.h"
#include <stdlib.h>
#include <string.h>

Head *makeList()
{
    Head *pHead = NULL;
    pHead = (Head *)malloc(sizeof(Head));
    if (NULL == pHead)
    {
        PRINT_ERROR("malloc head");
        exit(-1);
    }
    pHead->iNum = 0;
    pHead->pFirstNode = NULL;
    return pHead;   
}
Node *makeNode()
{
    Node *pNode = NULL;
    pNode = (Node *)malloc(sizeof(Node));
    if (NULL == pNode)
    {
        PRINT_ERROR("malloc node");
        exit(-1);
    }
    memset(pNode->caName, '\0', FILE_NAME_LEN);
    pNode->pNext = NULL;
    return pNode;
}
void initNode(Node *node, char *pFileName)
{
    if (NULL != node && NULL != pFileName)
    {
        strcpy(node->caName, pFileName);
    }
}
void insertList(Head *head, Node *node)
{
    if (NULL == head || NULL == node)
    {
        return;
    }
    if (NULL == head->pFirstNode)
    {
        head->pFirstNode = node;
    }
    else
    {
        node->pNext = head->pFirstNode;
        head->pFirstNode = node;
    }
    head->iNum++;
}
Node *findNode(Head *head, char *pFileName)
{
    Node *pNode = NULL;
    if (NULL != head && NULL != pFileName)
    {
        pNode = head->pFirstNode;
        while (NULL != pNode)
        {
            if (0 == strcmp(pNode->caName, pFileName))
            {
                return pNode;
            }
            pNode = pNode->pNext;
        }
    }
    return pNode;
}
void deleteNode(Head *head, char *pFileName)
{
    if (NULL != head && NULL != pFileName)
    {
        Node *pPreNode = head->pFirstNode;
        Node *pCurNode = pPreNode;
        while (NULL != pCurNode)
        {
            if (0 == strcmp(pCurNode->caName
                            , pFileName))
            {
                if (pCurNode == pPreNode)
                {
                    head->pFirstNode = pCurNode->pNext;
                }
                else
                {
                    pPreNode->pNext = pCurNode->pNext;
                }
                break;
            }
            pPreNode = pCurNode;
            pCurNode = pCurNode->pNext;
        }
        if (NULL != pCurNode)
        {
            free(pCurNode);
            pCurNode = NULL;
            head->iNum--;
        }
    }
}
void showList(Head *head)
{
    if (NULL != head)
    {
        Node *pNode = head->pFirstNode;
        while (NULL != pNode)
        {
            printf("name:%s\n", pNode->caName);
            pNode = pNode->pNext;
        }
    }
}
void destoryList(Head *head)
{
    if (NULL != head)
    {
        Node *pNode = head->pFirstNode;
        while (NULL != pNode)
        {
            head->pFirstNode = pNode->pNext;
            free(pNode);
            head->iNum--;
            pNode = head->pFirstNode;
        }
    }
}

void showNode(Node *node)
{
    if (NULL != node)
    {
        printf("name:%s\n", node->caName);
    }
}

protocol.h

#ifndef PROTOCOL_H
#define PROTOCOL_H

#include <stdio.h>

enum TYPE
{
    ENUM_TYPE_MIN = 0,
    ENUM_TYPE_ASK_FILE_INFO, //客户端请求文件信息
    ENUM_TYPE_RESP_FILE_INFO, //服务器返回文件信息

    ENUM_TYPE_UPLOAD_FILE, //客户端上传文件

    ENUM_TYPE_ASK_DOWNLOAD_FILE, //客户端请求下载文件
    ENUM_TYPE_RESP_DOWNLOAD_FILE, //服务器发送文件

    ENUM_TYPE_RENAME_FILE, //客户端重命名文件
    ENUM_TYPE_DELETE_FILE, //客户端删除文件

    ENUM_TYPE_MAX = 0x0fffffff
};

#define SERVER 0

typedef struct ChatPDU
{
    unsigned int iChatPDULen;   //数据单元总大小
    unsigned int iType;         //消息类型
    unsigned int iChatDataLen;  //消息大小
    char caFileName[32];        //文件名字
    unsigned int iFileSize;     //文件大小
    char chatData[4];           //发送的消息
}ChatPDU;

ChatPDU *makeChatPDU(int len);
int parsePDU(ChatPDU *pChatPDU);
void freePDU(ChatPDU *pChatPDU);

#endif

protocol.c

#if 1
#include "protocol.h"
#include "error.h"
#endif
#include <stdlib.h>
#include <string.h>

ChatPDU *makeChatPDU(int len)
{
    if (len <= 0)
    {
        return NULL;
    }
    ChatPDU *pChatPDU = (ChatPDU *)malloc(len);
    if (NULL == pChatPDU)
    {
        PRINT_ERROR("malloc PDU");
        exit(-1);
    }
    memset(pChatPDU, 0, len);
    return pChatPDU;
}
int parsePDU(ChatPDU *pChatPDU)
{
    if (NULL == pChatPDU)
    {
        return ENUM_TYPE_MIN;
    }
    return pChatPDU->iType;
}
void freePDU(ChatPDU *pChatPDU)
{
    if (NULL != pChatPDU)
    {
        free(pChatPDU);
        pChatPDU = NULL;
    }
}

chatServer.h

#ifndef CHAT_SERVER_H
#define CHAT_SERVER_H

#include <stdio.h>
#include <errno.h>
#include <string.h>
/*socket()  send()*/
#include <sys/types.h>
#include <sys/socket.h>

#include <netinet/in.h>
#include <unistd.h>  //fork()

/*wait()*/
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>  //signal()

#include <pthread.h>  //thread
#include "node.h"
#include "protocol.h"
#include "error.h"
#include "file.h"

#include <stdlib.h>  //exit()

int makeSocket();
void bindSocketAddr(int sockfd);
void listenClient(int sockfd);
void handle(int sockfd);

#endif

chatServer.c

#include "chatServer.h"

Head *g_pHead = NULL;
#define FILE_PATH "file/"

static void sendDataToClient(int sockfd
                             , const ChatPDU *pChatPDU)
{
    if (NULL == pChatPDU)
    {
        return;
    }
    int ret = 0;
    int iLeft = pChatPDU->iChatPDULen;
    int iSend = 0;
    ret = write(sockfd, pChatPDU, iLeft);
    iLeft -= ret;  //还有多少数据要发送
    iSend += ret;  //已发送的数据大小
    while (ret > 0 && iLeft)
    {
        ret = write(sockfd, (char *)pChatPDU+iSend, iLeft);
        iLeft -= ret;
        iSend += ret;
    }
}

static ChatPDU *readDataFromClient(int sockfd)
{
    int ret = 0;
    unsigned int iPDULen = 0;
    ret = read(sockfd, &iPDULen, sizeof(int));
    if (-1 == ret)
    {
        PRINT_ERROR("recv");
        return NULL;
    }
    printf("pdulen:%d\n", iPDULen);
    ChatPDU *pChatPDU = makeChatPDU(iPDULen);
    pChatPDU->iChatPDULen = iPDULen;

    int iLeft = iPDULen - ret;  //剩余的数据大小
    int iRecv = ret;   //已读的数据大小
    while (ret > 0 && iLeft)
    {
        ret = read(sockfd, (char*)pChatPDU+iRecv, iLeft);
        iRecv += ret;
        iLeft -= ret;
    }
    printf("datalen:%d\n", pChatPDU->iChatDataLen);
    return pChatPDU;
}

void sendFileListToClient(int sockfd)
{
    if (NULL == g_pHead)
    {
        return;
    }

    destoryList(g_pHead);
    scanFileIntoList(g_pHead, FILE_PATH);

    unsigned int iLen = sizeof(ChatPDU) + (g_pHead->iNum) * FILE_NAME_LEN - sizeof(int);
    ChatPDU *pChatPDU = NULL;
    pChatPDU = makeChatPDU(iLen);
    Node *pNode = g_pHead->pFirstNode;
    unsigned int i = 0;
    while (NULL != pNode)
    {
        memcpy(pChatPDU->chatData+i*FILE_NAME_LEN
               , pNode->caName, FILE_NAME_LEN);
        i++;
        pNode = pNode->pNext;
    }
    pChatPDU->iChatPDULen = iLen;
    pChatPDU->iChatDataLen = g_pHead->iNum * FILE_NAME_LEN;
    pChatPDU->iType = ENUM_TYPE_RESP_FILE_INFO;

    sendDataToClient(sockfd, pChatPDU);
    freePDU(pChatPDU);
    pChatPDU = NULL;
}

static void handleClientUploadFile(ChatPDU *pChatPDU)
{
    if (NULL == pChatPDU)
    {
        return;
    }
    char caPath[64] = FILE_PATH;
    strcat(caPath, pChatPDU->caFileName);
    int fd = openFile(caPath);

    char caBuf[FILE_IO_MAX_LEN+1] = {'\0'};
    memset(caBuf, '\0', FILE_IO_MAX_LEN+1);
    strncpy(caBuf, pChatPDU->chatData, pChatPDU->iChatDataLen);
    lseek(fd, 0, SEEK_END);
    writeDataToFile(fd, caBuf, pChatPDU->iChatDataLen);
    closeFile(fd);
}

static void handleClientDownloadFile(int sockfd, ChatPDU *pChatPDU)
{
    if (NULL != pChatPDU)
    {
        char caPath[64] = FILE_PATH;
        strcat(caPath, pChatPDU->caFileName);
        int fd = openFile(caPath);
        int iFileSize = lseek(fd, 0, SEEK_END);
        int ret = -1;

        int iLen = sizeof(ChatPDU)-sizeof(int)+FILE_IO_MAX_LEN;
        ChatPDU *pChatPDUSend = makeChatPDU(iLen);

        pChatPDUSend->iChatPDULen = iLen;
        pChatPDUSend->iType = ENUM_TYPE_RESP_DOWNLOAD_FILE;
        strcpy(pChatPDUSend->caFileName, pChatPDU->caFileName);
        pChatPDUSend->iFileSize = iFileSize;
        printf("file size = %d\n", pChatPDUSend->iFileSize);
        char caData[FILE_IO_MAX_LEN];
        lseek(fd, 0, SEEK_SET);
        while (ret = read(fd, caData, FILE_IO_MAX_LEN))
        {
            pChatPDUSend->iChatDataLen = ret;
            memcpy(pChatPDUSend->chatData, caData, ret);
            printf("data len = %d\n", ret);
            sendDataToClient(sockfd, pChatPDUSend);
        }
        freePDU(pChatPDU);
        freePDU(pChatPDUSend);
    }
}

static void *handleClient(void *arg)
{
    int sockfd = (int)arg;
    ChatPDU *pChatPDU = NULL;
    int iMsgType = 0;
    while (1)
    {
        /*获得PDU*/
        pChatPDU = readDataFromClient(sockfd);
        if (NULL != pChatPDU)
        {
            /*解析PDU*/
            iMsgType = parsePDU(pChatPDU);
            switch (iMsgType)
            {
            //客户端请求查看所有文件
            case ENUM_TYPE_ASK_FILE_INFO:
                freePDU(pChatPDU);
                pChatPDU = NULL;
                sendFileListToClient(sockfd);
                break;
            //客户端上传文件
            case ENUM_TYPE_UPLOAD_FILE:
                handleClientUploadFile(pChatPDU);
                freePDU(pChatPDU);
                pChatPDU = NULL;
                break;
            //客户端请求下载文件
            case ENUM_TYPE_ASK_DOWNLOAD_FILE:
                handleClientDownloadFile(sockfd, pChatPDU);
                break;
            //客户端修改文件名
            case ENUM_TYPE_RENAME_FILE:
                break;
            //客户端删除文件
            case ENUM_TYPE_DELETE_FILE:
                break;
            default:
                break;
            }
        }
    }
}

int makeSocket()
{
    int sockfd = 0;
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (-1 == sockfd)
    {
        PRINT_ERROR("socket");
        exit(-1);
    }
    return sockfd;
}

void bindSocketAddr(int sockfd)
{
    struct sockaddr_in servaddr;
    //地址协议:ipv4
    servaddr.sin_family = AF_INET;
    //服务器端口
    servaddr.sin_port = htons(8668);
    //服务器ip
    servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
    bzero(&(servaddr.sin_zero), 8);
    int ret = bind(sockfd
                   , (struct sockaddr *)&servaddr
                   , sizeof(struct sockaddr));
    if (-1 == ret)
    {
        PRINT_ERROR("bind");
        exit(-1);
    }
}
void listenClient(int sockfd)
{
    int ret = listen(sockfd, 10);
    if (-1 == ret)
    {
        PRINT_ERROR("listen");
        exit(-1);
    }
}

static void acceptClient(int sockfd)
{
    struct sockaddr_in clientaddr;
    int iLen = sizeof(struct sockaddr);
    int sockClient = 0;
    pthread_t pt;
    int ret = 0;
    while (1)
    {
        printf("accepting client connect...\n");
        //服务器通过sockClient和客户端进行通信
        //clientaddr:用来保存客户端地址等信息
        //accept():阻塞等待客户端的连接
        sockClient = accept(sockfd
                    , (struct sockaddr *)&clientaddr
                    , &iLen);
        printf("after accepted client\n");
        ret = pthread_create(&pt, NULL, handleClient
                             , (void *)sockClient);
        if (0 != ret)
        {
            PRINT_ERROR("pthread_create");
            exit(-1);
        }
//      pthread_detach(pt);
    }
}

void handle(int sockfd)
{
    g_pHead = makeList();
    //scanFileIntoList(g_pHead, FILE_PATH);
    showList(g_pHead);

    acceptClient(sockfd);
}

main(server)

#include "chatServer.h"

int main(void)
{
    int sockfd = -1;
    sockfd = makeSocket();
    bindSocketAddr(sockfd); 
    listenClient(socakfd);
    handle(sockfd);

    return 0;
}

test.c

#include <stdio.h>

int main(void)
{
    printf("%d\n", 24323236 % 4096);

    return 0;
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,524评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,869评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,813评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,210评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,085评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,117评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,533评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,219评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,487评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,582评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,362评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,218评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,589评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,899评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,176评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,503评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,707评论 2 335

推荐阅读更多精彩内容