Linux C Socket编程:文件上传

一个服务端等待, 客户端上传文件到服务端,通过输入要上传的文件名,目前只做到仅对当前执行文件的目录下的文件,应该在服务端收到文件路径之后进行处理的。

服务端代码:

  1 #include <netinet/in.h>    // for sockaddr_in
  2 #include <sys/types.h>    // for socket
  3 #include <sys/socket.h>    // for socket
  4 #include <stdio.h>        // for printf
  5 #include <stdlib.h>        // for exit
  6 #include <string.h>        // for bzero
  7 
  8 #define SERVER_PORT 6666
  9 #define LISTEN_QUEUE  20
 10 #define BUFFER_SIZE 1024
 11 #define FILE_NAME_MAX_SIZE 512
 12 
 13 int main(int argc, char **argv)
 14 {
 15     //设置一个socket地址结构server_addr,代表服务器internet地址, 端口
 16     struct sockaddr_in server_addr;
 17     bzero(&server_addr, sizeof(server_addr)); //把一段内存区的内容全部设置为0
 18     server_addr.sin_family = AF_INET;
 19     server_addr.sin_addr.s_addr = htons(INADDR_ANY);
 20     server_addr.sin_port = htons(SERVER_PORT);
 21 
 22     //创建用于internet的流协议(TCP)socket,用server_socket代表服务器socket
 23     int server_socket = socket(PF_INET, SOCK_STREAM, 0);
 24     if (server_socket < 0)
 25     {
 26         printf("Create Socket Failed!");
 27         exit(1);
 28     }
 29 
 30     //把socket和socket地址结构联系起来
 31     if (bind(server_socket, (struct sockaddr*) &server_addr,
 32             sizeof(server_addr)))
 33     {
 34         printf("Server Bind Port: %d Failed!
", SERVER_PORT);
 35         exit(1);
 36     }
 37 
 38     //server_socket用于监听
 39     if (listen(server_socket, LISTEN_QUEUE))
 40     {
 41         printf("Server Listen Failed!");
 42         exit(1);
 43     }
 44 
 45     while (1)
 46     {
 47         //定义客户端的socket地址结构client_addr
 48         char buffer[BUFFER_SIZE];
 49         struct sockaddr_in client_addr;
 50         socklen_t length = sizeof(client_addr);
 51 
 52         int client_socket = accept(server_socket,
 53                 (struct sockaddr*) &client_addr, &length);
 54         if (client_socket < 0)
 55         {
 56             printf("Server Accept Failed!
");
 57             break;
 58         }
 59         bzero(buffer, BUFFER_SIZE);
 60         // 获取客户端要传输的文件名
 61         length = recv(client_socket, buffer, BUFFER_SIZE, 0);
 62         if (length < 0)
 63         {
 64             printf("Server Recieve Data Failed!
");
 65             break;
 66         }
 67         char file_name[FILE_NAME_MAX_SIZE + 1];
 68         bzero(file_name, FILE_NAME_MAX_SIZE + 1);
 69         strncpy(
 70                 file_name,
 71                 buffer,
 72                 strlen(buffer) > FILE_NAME_MAX_SIZE? FILE_NAME_MAX_SIZE : strlen(buffer));
 73 
 74         // 新建文件
 75         FILE * fp = fopen(file_name, "w");
 76         if (NULL == fp)
 77         {
 78             printf("File: %s CAN NOT WRITE!
", file_name);
 79         }
 80         else
 81         {
 82             bzero(buffer, BUFFER_SIZE);
 83             int file_block_length = 0;
 84             while ((file_block_length = recv(client_socket, buffer, BUFFER_SIZE, 0)) > 0)
 85             {
 86                 if (file_block_length < 0)
 87                 {
 88                     printf("Recieve Data From Client Failed!
");
 89                     break;
 90                 }
 91                 int write_length = fwrite(buffer, sizeof(char), file_block_length, fp);
 92                 if (write_length < file_block_length)
 93                 {
 94                     printf("File: %s Write Failed
", file_name);
 95                     break;
 96                 }
 97                 bzero(buffer, BUFFER_SIZE);
 98             }
 99             fclose(fp);
100             printf("File: %s Transfer Finished

", file_name);
101         }
102         //关闭与客户端的连接
103         close(client_socket);
104     }
105     //关闭监听用的socket
106     close(server_socket);
107     return 0;
108 }
View Code

客户端代码:

  1 #include <netinet/in.h>    // for sockaddr_in
  2 #include <sys/types.h>    // for socket
  3 #include <sys/socket.h>    // for socket
  4 #include <stdio.h>        // for printf
  5 #include <stdlib.h>        // for exit
  6 #include <string.h>        // for bzero
  7 /*
  8  #include <sys/types.h>
  9  #include <sys/stat.h>
 10  #include <fcntl.h>
 11  #include <unistd.h>
 12  */
 13 
 14 #define SERVER_PORT 6666
 15 #define BUFFER_SIZE 1024
 16 #define FILE_NAME_MAX_SIZE 512
 17 
 18 int main(int argc, char **argv)
 19 {
 20     if (argc != 2)
 21     {
 22         printf("Please input the IP address of the server 
", argv[0]);
 23         exit(1);
 24     }
 25 
 26     //设置一个socket地址结构client_addr,代表客户机internet地址, 端口
 27     struct sockaddr_in client_addr;
 28     bzero(&client_addr, sizeof(client_addr)); //把一段内存区的内容全部设置为0
 29     client_addr.sin_family = AF_INET; //internet协议族
 30     client_addr.sin_addr.s_addr = htons(INADDR_ANY); //INADDR_ANY表示自动获取本机地址
 31     client_addr.sin_port = htons(0); //0表示让系统自动分配一个空闲端口
 32     //创建用于internet的流协议(TCP)socket,用client_socket代表客户机socket
 33     int client_socket = socket(AF_INET, SOCK_STREAM, 0);
 34     if (client_socket < 0)
 35     {
 36         printf("Create Socket Failed!
");
 37         exit(1);
 38     }
 39     //把客户机的socket和客户机的socket地址结构联系起来
 40     if (bind(client_socket, (struct sockaddr*) &client_addr,
 41             sizeof(client_addr)))
 42     {
 43         printf("Client Bind Port Failed!
");
 44         exit(1);
 45     }
 46 
 47     //设置一个socket地址结构server_addr,代表服务器的internet地址, 端口
 48     struct sockaddr_in server_addr;
 49     bzero(&server_addr, sizeof(server_addr));
 50     server_addr.sin_family = AF_INET;
 51     if (inet_aton(argv[1], &server_addr.sin_addr) == 0) //服务器的IP地址来自程序的参数
 52     {
 53         printf("Server IP Address Error! 
");
 54         exit(1);
 55     }
 56 
 57     server_addr.sin_port = htons(SERVER_PORT);
 58     socklen_t server_addr_length = sizeof(server_addr);
 59     // 向服务器发起连接,连接成功后client_socket代表了客户机和服务器的一个socket连接
 60     if (connect(client_socket, (struct sockaddr*) &server_addr,
 61             server_addr_length) < 0)
 62     {
 63         printf("Can Not Connect To %s!
", argv[1]);
 64         exit(1);
 65     }
 66 
 67     // 连接上服务器, 选择要上传的文件
 68     char file_name[FILE_NAME_MAX_SIZE + 1];bzero
 69     (file_name, FILE_NAME_MAX_SIZE + 1);
 70     printf("Please Input File Name Upload To Server: ");
 71     scanf("%s", file_name);
 72 
 73     char buffer[BUFFER_SIZE];
 74     bzero(buffer, BUFFER_SIZE);
 75     strncpy(buffer, file_name,
 76             strlen(file_name) > BUFFER_SIZE? BUFFER_SIZE : strlen(file_name));
 77 
 78     FILE * fp = fopen(file_name, "r");
 79     if (NULL == fp)
 80     {
 81         printf("File: %s NOT FOUND! 
", file_name);
 82         exit(1);
 83     }
 84 
 85     // 发送文件名
 86     int nameLength = send(client_socket, buffer, BUFFER_SIZE, 0);
 87     if (nameLength < 0)
 88     {
 89         printf("File name Error! 
");
 90         exit(0);
 91     }
 92 
 93     bzero(buffer, BUFFER_SIZE);
 94     int file_block_length = 0;
 95 
 96     while ((file_block_length = fread(buffer, sizeof(char), BUFFER_SIZE, fp))
 97             > 0)
 98     {
 99         if (send(client_socket, buffer, file_block_length, 0) < 0)
100         {
101             printf("Send File:	%s Failed
", file_name);
102             break;
103         }
104         bzero(buffer, BUFFER_SIZE);
105     }
106     printf("File:	%s Transfer Finished
", file_name);
107     fclose(fp);
108     close(client_socket);
109     return 0;
110 }
View Code

代码很多是复制的,慢慢看一行行看懂之后把原来别人的客户端下载改成客户端上传,其实都差不多,服务端与客户端connect之后基本上就是文件读写的事了。

来自:http://www.cnblogs.com/lycheng/archive/2011/11/08/2240518.html

原文地址:https://www.cnblogs.com/tianciliangen/p/3400958.html