国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Linux > 正文

Linux網絡編程6——使用TCP實現文件服務器

2024-06-28 13:24:24
字體:
來源:轉載
供稿:網友
linux網絡編程6——使用TCP實現文件服務器需求

當客戶端連接上服務器后,服務器會將相應文件傳輸給客戶端,實現文件下載。

思路

服務器端,主進程負責listen。循環內,主進程每從任務請求隊列中accept出一個請求,就fork出孫子完成文件傳輸。注意:如果只是fork出兒子,那么主進程就得wait兒子,這樣的話,只有當給一個客戶端傳完文件后才能下一個。

代碼

server端

/*************************************************************************  > File Name: server.c  > Author: KrisChou  > Mail:zhoujx0219@163.com   > Created Time: Thu 28 Aug 2014 09:40:32 PM CST ************************************************************************/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <unistd.h>#include <netdb.h>#define SNDSIZE 1024*1024 //1M,注意如果棧空間(可以設置的)沒這么大,就用堆空間#define FILE_NAME  "a.rmvb"int main(int argc,char* argv[])// exe config{    /* 從配置文件中讀取服務器聯系方式:ip以及端口號 */    int fd_conf ;    fd_conf = open(argv[1], O_RDONLY) ;    FILE* fp_conf = fdopen(fd_conf, "r"); //秀一下fdopen函數,文件描述符轉換為文件指針 fdopen(int fd, const char *mode)    char my_ip[32]="";    int my_port ;    fscanf(fp_conf, "%s%d", my_ip, &my_port);    close(fd_conf);    fclose(fp_conf);    /* 創建服務器的監聽socket端口 */    int fd_listen    fd_listen = socket(AF_INET, SOCK_STREAM, 0);    if(fd_listen == -1)    {        perror("socket");    }    /* 為服務器socket端口綁定聯系方式,以便讓客戶端connect */        struct sockaddr_in  server_addr ;    memset(&server_addr, 0, sizeof(server_addr));    server_addr.sin_family = AF_INET ;    server_addr.sin_port = htons(my_port);    server_addr.sin_addr.s_addr  = inet_addr(my_ip);    if(-1 == bind(fd_listen, (struct sockaddr *)&server_addr, sizeof(server_addr)) )    {        perror("bind");        close(fd_listen);        exit(1);    }    /* listen */    if(-1 == listen(fd_listen, 5))    {        perror("listen");        close(fd_listen);        exit(1);    }        /* accept */    int fd_client;  /* 客戶端socket端口的另一頭 */    struct sockaddr_in client_addr ; /* 客戶端聯系方式,以accept函數的傳出參數給出 */    int len ;    memset(&client_addr, 0, sizeof(client_addr));    len = sizeof(client_addr);    while(1)    {        fd_client = accept(fd_listen, (struct sockaddr *)&client_addr, &len);        if(fd_client == -1)         {            continue ;        }        PRintf("a client connect ! ip:port  %s:%d/n",inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port));        if(fork() == 0)        {            close(fd_listen); //對于子進程和孫子進程都不需要listen端口,直接關閉。            if(fork() == 0)            {                int fd_file = open(FILE_NAME, O_RDONLY); //打開客戶端要下載的文件                char buf[SNDSIZE] ;                int snd_cnt = 0 ;                int readn ;                /* 從文件中讀取數據,并發送給客戶端 */                while(memset(buf, 0,SNDSIZE ), (readn = read(fd_file,buf, SNDSIZE)) > 0)                {                        if(send(fd_client, buf, readn, 0) != readn)                        {                            printf("send error! /n");                        }                        snd_cnt ++ ;                }                printf("send over: %d /n", snd_cnt);                close(fd_file);                close(fd_client);                exit(0);            }            close(fd_client);            exit(0);        }        close(fd_client);        wait(NULL) ;    }    return 0 ;}

client端

/*************************************************************************    > File Name: client.c    > Author: KrisChou    > Mail:zhoujx0219@163.com     > Created Time: Thu 28 Aug 2014 11:59:20 PM CST ************************************************************************/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <unistd.h>#include <netdb.h>#define SNDSIZE 1024*1024#define SERVER_PORT 6080 // 服務器端口int main(int argc, char *argv[]) EXE IP{    /* socket */    int fd_client;    fd_client = socket(AF_INET, SOCK_STREAM, 0);    if(fd_client == -1)    {        perror("socket");        exit(1);    }    /* 存放所連服務器信息的結構體 */    struct sockaddr_in server_addr;    memset(&server_addr,0,sizeof(server_addr));    server_addr.sin_family = AF_INET;    server_addr.sin_port = htons(SERVER_PORT);    server_addr.sin_addr.s_addr = inet_addr(argv[1]);    /* connect */    while(connect(fd_client, (struct sockaddr *)&server_addr,sizeof(server_addr)) == -1)    {        /* 當connect返回-1時,說明服務器還沒有啟動 */        sleep(1);        printf("connecting... /n");    }    printf("connect success! /n");    int fd_write = open("txt", O_WRONLY | O_CREAT);//下載的內容寫入本地文件中    char buf[SNDSIZE];    int readn;    int recv_cnt = 0;    while(memset(buf,0,SNDSIZE),(readn = recv(fd_client,buf,SNDSIZE,0)) > 0)    {        write(fd_write,buf,readn);        recv_cnt++;    }    printf("recv over: %d /n", recv_cnt);    close(fd_write);    close(fd_client);    return 0;}

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 加查县| 依安县| 宝坻区| 杭锦后旗| 高阳县| 苏尼特左旗| 平阴县| 日土县| 乌审旗| 恩平市| 延安市| 改则县| 高台县| 孙吴县| 张家港市| 阳城县| 滦南县| 剑河县| 普安县| 卫辉市| 牙克石市| 来宾市| 尉犁县| 荥经县| 上栗县| 彰化市| 电白县| 安塞县| 姚安县| 甘洛县| 德钦县| 荣昌县| 罗甸县| 鄄城县| 江源县| 南投县| 含山县| 建平县| 卫辉市| 汤阴县| 伊吾县|