基于TCP流协议的socket网络文件传输Demo:

实现:C语言
功能:文件传输(可以传任何格式的文件)

/*************************************************************************
        > File Name: Server.c
        > Author: SongLee
        > E-mail: lisong.shine@qq.com
        > Created Time: 2014年03月13日 星期四 22时17分43秒
        > Personal Blog: http://songlee24.github.io/
     ************************************************************************/
     
    #include<netinet/in.h>  // sockaddr_in
    #include<sys/types.h>   // socket
    #include<sys/socket.h>  // socket
    #include<stdio.h>       // printf
    #include<stdlib.h>      // exit
    #include<string.h>      // bzero
     
    #define SERVER_PORT 8000
    #define LENGTH_OF_LISTEN_QUEUE 20
    #define BUFFER_SIZE 1024
    #define FILE_NAME_MAX_SIZE 512
     
    int main(void)
    {
        // 声明并初始化一个服务器端的socket地址结构
        struct sockaddr_in server_addr;
        bzero(&server_addr, sizeof(server_addr));
        server_addr.sin_family = AF_INET;
        server_addr.sin_addr.s_addr = htons(INADDR_ANY);
        server_addr.sin_port = htons(SERVER_PORT);
     
        // 创建socket,若成功,返回socket描述符
        int server_socket_fd = socket(PF_INET, SOCK_STREAM, 0);
        if(server_socket_fd < 0)
        {
            perror("Create Socket Failed:");
            exit(1);
        }
        int opt = 1;
        setsockopt(server_socket_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
     
        // 绑定socket和socket地址结构
        if(-1 == (bind(server_socket_fd, (struct sockaddr*)&server_addr, sizeof(server_addr))))
        {
            perror("Server Bind Failed:");
            exit(1);
        }
        
        // socket监听
        if(-1 == (listen(server_socket_fd, LENGTH_OF_LISTEN_QUEUE)))
        {
            perror("Server Listen Failed:");
            exit(1);
        }
     
        while(1)
        {
            // 定义客户端的socket地址结构
            struct sockaddr_in client_addr;
            socklen_t client_addr_length = sizeof(client_addr);
     
            // 接受连接请求,返回一个新的socket(描述符),这个新socket用于同连接的客户端通信
            // accept函数会把连接到的客户端信息写到client_addr中
            int new_server_socket_fd = accept(server_socket_fd, (struct sockaddr*)&client_addr, &client_addr_length);
            if(new_server_socket_fd < 0)
            {
                perror("Server Accept Failed:");
                break;
            }
     
            // recv函数接收数据到缓冲区buffer中
            char buffer[BUFFER_SIZE];
            bzero(buffer, BUFFER_SIZE);
            if(recv(new_server_socket_fd, buffer, BUFFER_SIZE, 0) < 0)
            {
                perror("Server Recieve Data Failed:");
                break;
            }
     
            // 然后从buffer(缓冲区)拷贝到file_name中
            char file_name[FILE_NAME_MAX_SIZE+1];
            bzero(file_name, FILE_NAME_MAX_SIZE+1);
            strncpy(file_name, buffer, strlen(buffer)>FILE_NAME_MAX_SIZE?FILE_NAME_MAX_SIZE:strlen(buffer));
            printf("%s\n", file_name);
     
            // 打开文件并读取文件数据
            FILE *fp = fopen(file_name, "r");
            if(NULL == fp)
            {
                printf("File:%s Not Found\n", file_name);
            }
            else
            {
                bzero(buffer, BUFFER_SIZE);
                int length = 0;
                // 每读取一段数据,便将其发送给客户端,循环直到文件读完为止
                while((length = fread(buffer, sizeof(char), BUFFER_SIZE, fp)) > 0)
                {
                    if(send(new_server_socket_fd, buffer, length, 0) < 0)
                    {
                        printf("Send File:%s Failed./n", file_name);
                        break;
                    }
                    bzero(buffer, BUFFER_SIZE);
                }
     
                // 关闭文件
                fclose(fp);
                printf("File:%s Transfer Successful!\n", file_name);
            }
            // 关闭与客户端的连接
            close(new_server_socket_fd);
        }
        // 关闭监听用的socket
        close(server_socket_fd);
        return 0;
    }

/*************************************************************************
        > File Name: Client.c
        > Author: SongLee
        > E-mail: lisong.shine@qq.com
        > Created Time: 2014年03月14日 星期五 09时41分46秒
        > Personal Blog: http://songlee24.github.io/
     ************************************************************************/
     
    #include<netinet/in.h>   // sockaddr_in
    #include<sys/types.h>    // socket
    #include<sys/socket.h>   // socket
    #include<stdio.h>        // printf
    #include<stdlib.h>       // exit
    #include<string.h>       // bzero
     
    #define SERVER_PORT 8000
    #define BUFFER_SIZE 1024
    #define FILE_NAME_MAX_SIZE 512
     
    int main()
    {
        // 声明并初始化一个客户端的socket地址结构
        struct sockaddr_in client_addr;
        bzero(&client_addr, sizeof(client_addr));
        client_addr.sin_family = AF_INET;
        client_addr.sin_addr.s_addr = htons(INADDR_ANY);
        client_addr.sin_port = htons(0);
     
        // 创建socket,若成功,返回socket描述符
        int client_socket_fd = socket(AF_INET, SOCK_STREAM, 0);
        if(client_socket_fd < 0)
        {
            perror("Create Socket Failed:");
            exit(1);
        }
     
        // 绑定客户端的socket和客户端的socket地址结构 非必需
        if(-1 == (bind(client_socket_fd, (struct sockaddr*)&client_addr, sizeof(client_addr))))
        {
            perror("Client Bind Failed:");
            exit(1);
        }
     
        // 声明一个服务器端的socket地址结构,并用服务器那边的IP地址及端口对其进行初始化,用于后面的连接
        struct sockaddr_in server_addr;
        bzero(&server_addr, sizeof(server_addr));
        server_addr.sin_family = AF_INET;
        if(inet_pton(AF_INET, "127.0.0.1", &server_addr.sin_addr) == 0)
        {
            perror("Server IP Address Error:");
            exit(1);
        }
        server_addr.sin_port = htons(SERVER_PORT);
        socklen_t server_addr_length = sizeof(server_addr);
     
        // 向服务器发起连接,连接成功后client_socket_fd代表了客户端和服务器的一个socket连接
        if(connect(client_socket_fd, (struct sockaddr*)&server_addr, server_addr_length) < 0)
        {
            perror("Can Not Connect To Server IP:");
            exit(0);
        }
     
        // 输入文件名 并放到缓冲区buffer中等待发送
        char file_name[FILE_NAME_MAX_SIZE+1];
        bzero(file_name, FILE_NAME_MAX_SIZE+1);
        printf("Please Input File Name On Server:\t");
        scanf("%s", file_name);
     
        char buffer[BUFFER_SIZE];
        bzero(buffer, BUFFER_SIZE);
        strncpy(buffer, file_name, strlen(file_name)>BUFFER_SIZE?BUFFER_SIZE:strlen(file_name));
        
        // 向服务器发送buffer中的数据
        if(send(client_socket_fd, buffer, BUFFER_SIZE, 0) < 0)
        {
            perror("Send File Name Failed:");
            exit(1);
        }
     
        // 打开文件,准备写入
        FILE *fp = fopen(file_name, "w");
        if(NULL == fp)
        {
            printf("File:\t%s Can Not Open To Write\n", file_name);
            exit(1);
        }
     
        // 从服务器接收数据到buffer中
        // 每接收一段数据,便将其写入文件中,循环直到文件接收完并写完为止
        bzero(buffer, BUFFER_SIZE);
        int length = 0;
        while((length = recv(client_socket_fd, buffer, BUFFER_SIZE, 0)) > 0)
        {
            if(fwrite(buffer, sizeof(char), length, fp) < length)
            {
                printf("File:\t%s Write Failed\n", file_name);
                break;
            }
            bzero(buffer, BUFFER_SIZE);
        }
     
        // 接收成功后,关闭文件,关闭socket
        printf("Receive File:\t%s From Server IP Successful!\n", file_name);
        close(fp);
        close(client_socket_fd);
        return 0;
    }
---------------------
作者:神奕
来源:CSDN
原文:https://blog.csdn.net/lisonglisonglisong/article/details/22699675
版权声明:本文为博主原创文章,转载请附上博文链接!

Linux网络编程:socket文件传输范例的更多相关文章

  1. linux网络编程-socket(37)

    在编程的时候需要加上对应pthread开头的头文件,gcc编译的时候需要加了-lpthread选项 第三个参数是线程的入口参数,函数的参数是void*,返回值是void*,第四个参数传递给线程函数的参 ...

  2. Linux网络编程socket选项之SO_LINGER,SO_REUSEADDR

    from http://blog.csdn.net/feiyinzilgd/article/details/5894300 Linux网络编程中,socket的选项很多.其中几个比较重要的选项有:SO ...

  3. Linux入门培训教程 linux网络编程socket介绍

    一.概念介绍 网络程序分为服务端程序和客户端程序.服务端即提供服务的一方,客户端为请求服务的一方.但实际情况是有些程序的客户端.服务器端角色不是这么明显,即互为Linux培训 客户端和服务端. 我们编 ...

  4. Linux网络编程-----Socket地址API

    (1) 通用socket地址 socket网络编程接口中表示socket地址的是结构体sockaddr,其定义如下: #include<bits/socket.h> struct sock ...

  5. linux网络编程之断点传输文件

    以下载链接"http://www.boa.org/boa-0.94.13.tar.gz"为例: 断点续传实验大概步骤: ===================== 1,使用geth ...

  6. Linux网络编程--socket

    1.socket的核心思想是,作为服务器间的进程间通信的最底层的实现,常用的大部分网络协议都是基于socket实现. 2.socket 是如何与最终的低层收发包建立联系的? 3.socket 是如何与 ...

  7. Linux网络编程socket错误分析

    socket错误码: EINTR: 阻塞的操作被取消阻塞的调用打断.如设置了发送接收超时,就会遇到这种错误. 只能针对阻塞模式的socket.读,写阻塞的socket时,-1返回,错误号为INTR.另 ...

  8. linux网络编程-socket(2)

    当客户端调用close函数的时候,服务器的read函数读到的数据是0读到文件结束通知,表示对端关闭了tcp连接 我们现实实现下面的功能: 1.tcp客户端从标准的输入流中得到输入数据发送到服务器,服务 ...

  9. Linux网络编程系列-TCP传输控制

    滑动窗口(sliding window) 滑动窗口是用于流量控制的,发送端根据接收端的处理能力发送数据,不至于造成过多的丢包. 是发送方和接收方间的协调,对方的接收窗口大小就是自己的发送窗口大小. 在 ...

随机推荐

  1. linux下各目录的作用

    这么久了,一直觉得对于linux的运作情况还是懵懵懂懂的样子,刚才专门又看了一下 linux 下各目录的作用,记下来,以备以后再忘了. 下面内容来自:http://www.linuxidc.com/L ...

  2. samba 设置文件的读写权限

    原文:https://blog.csdn.net/lan120576664/article/details/50396511 打开配置文件 sudo pico /etc/samba/smb.conf ...

  3. python 全栈开发,Day59(小米商城)

    一.小米商城 准备工作: 访问iconfont,官网链接: http://www.iconfont.cn/ 登录之后,找到需要的图标 将图标下载到本地,解压,重命名为font创建几个空文件夹:css, ...

  4. C# mongoDB Driver 使用对象方式查询语法大全

    #region 查询方法 /// <summary> /// 获取单个对象 /// </summary> /// <typeparam name="T" ...

  5. Eclipse中打包maven项目-war包方式

    IntelliJ IDEA打包成war(包括maven项目)点击打开链接 首先要在maven项目中的pom.XML中配置好需要的配置: <project xmlns="http://m ...

  6. openstack安装-计算节点-nova计算服务安装

    一.基础服务安装 先安装基础工具 yum install net-tools vim telnet wget lrzsz 1.添加hosts解析 cat << EOF >/etc/h ...

  7. 【AtCoder】CODE FESTIVAL 2017 qual A

    A - Snuke's favorite YAKINIKU -- #include <bits/stdc++.h> #define fi first #define se second # ...

  8. linux下实现shell脚本自动连接mongodb数据库并创建索引

    在linux下创建shell脚本

  9. Educational Codeforces Round 26 E - Vasya's Function

    数论题还是好恶心啊. 题目大意:给你两个不超过1e12的数 x,y,定义一个f ( x, y ) 如果y==0 返回 0 否则返回1+ f ( x , y - gcd( x , y ) ); 思路:我 ...

  10. A+B Problem(再升级)

    洛谷P1832 A+B Problem(再升级) ·给定一个正整数n,求将其分解成若干个素数之和的方案总数. 先说我的垃圾思路,根本没有验证它的正确性就xjb写的,过了垃圾样例,还水了20分,笑哭.. ...