Chinaunix首页 | 论坛 | 博客
  • 博客访问: 376773
  • 博文数量: 47
  • 博客积分: 967
  • 博客等级: 准尉
  • 技术积分: 1290
  • 用 户 组: 普通用户
  • 注册时间: 2012-05-25 16:14
文章分类

全部博文(47)

文章存档

2019年(1)

2014年(1)

2013年(9)

2012年(36)

分类: LINUX

2012-11-03 13:29:24

    写完了一个简单的聊天程序,我想如果我们要发送一个文件给对方的话,应该也可以用这个解决。其实我感觉TCP服务器端依次调用socket()、bind()、listen()之后,就会监听指定的socket地址了。TCP客户端依次调用socket()、connect()之后就向TCP服务器发送了一个连接请求。TCP服务器监听到这个请求之后,就会调用accept()函数去接收请求,这样连接就建立好了。之后就可以开始网络I/O操作了,即类同于普通文件的读写I/O操作。如果我们要实现文本信息传输的话只需要用send()和recv()函数就可以实现了。如果要实现文件传输的话只需从文件中读取出来在用send()发送,然后recv()接受的话再存到文件里就OK了。
  下面是实现的是客户端向服务端发送一个文件名,然后服务端接受到这个名字之后将该文件传送给客户端:

ser.c

  1. #include<netinet/in.h>
  2. #include<sys/types.h>
  3. #include<sys/socket.h>
  4. #include<stdio.h>
  5. #include<stdlib.h>
  6. #include<string.h>
  7.   
  8. #define PORT 5552
  9. #define LISTEN 20
  10. #define BUFFER_SIZE 1024
  11. #define 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));
  18.     server_addr.sin_family = AF_INET;
  19.     server_addr.sin_addr.s_addr = htons(INADDR_ANY);
  20.     server_addr.sin_port = htons(PORT);
  21.   
  22.     // 创建用于internet的流协议(TCP)socket,用server_socket代表服务器向客户端提供服务的接口
  23.     int server_socket = socket(PF_INET, SOCK_STREAM, 0);
  24.     if (server_socket < 0)
  25.     {
  26.         printf("Create Socket Failed!\n");
  27.         exit(1);
  28.     }
  29.   
  30.     // 把socket和socket地址结构绑定
  31.     if (bind(server_socket, (struct sockaddr*)&server_addr, sizeof(server_addr)))
  32.     {
  33.         printf("Server Bind Port: %d Failed!\n",PORT);
  34.         exit(1);
  35.     }
  36.   
  37.     // server_socket用于监听
  38.     if (listen(server_socket,LISTEN))
  39.     {
  40.         printf("Server Listen Failed!\n");
  41.         exit(1);
  42.     }
  43.   
  44.     // 服务器端一直运行用以持续为客户端提供服务
  45.     while(1)
  46.     {
  47.         struct sockaddr_in client_addr;
  48.         socklen_t length = sizeof(client_addr);

  49.         // accpet返回一个新的socket,这个socket用来与此次连接到server的client进行通信
  50.         int new_server_socket = accept(server_socket, (struct sockaddr*)&client_addr, &length);
  51.         if (new_server_socket < 0)
  52.         {
  53.             printf("Server Accept Failed!\n");
  54.             break;
  55.         }
  56.   
  57.         char buffer[BUFFER_SIZE];
  58.         memset(buffer,0,sizeof(buffer));
  59.         length = recv(new_server_socket, buffer, BUFFER_SIZE, 0);
  60.         if (length < 0)
  61.         {
  62.             printf("Server Recieve Data Failed!\n");
  63.             break;
  64.         }
  65.   
  66.         char file_name[MAX_SIZE + 1];
  67.         memset(file_name,0,sizeof(file_name));
  68.         strncpy(file_name, buffer,
  69.                 strlen(buffer) > MAX_SIZE ? MAX_SIZE : strlen(buffer));
  70.   
  71.         FILE *fp = fopen(file_name, "r");
  72.         if (fp == NULL)
  73.         {
  74.             printf("File:\t%s Not Found!\n", file_name);
  75.         }
  76.         else
  77.         {
  78.             memset(buffer,0, BUFFER_SIZE);
  79.             int file_block_length = 0;
  80.             while( (file_block_length = fread(buffer, sizeof(char), BUFFER_SIZE, fp)) > 0)
  81.             {
  82.                 printf("file_block_length = %d\n", file_block_length);
  83.   
  84.                 // 发送buffer中的字符串到new_server_socket,实际上就是发送给客户端
  85.                 if (send(new_server_socket, buffer, file_block_length, 0) < 0)
  86.                 {
  87.                     printf("Send File:\t%s Failed!\n", file_name);
  88.                     break;
  89.                 }
  90.   
  91.                 memset(buffer,0,sizeof(buffer));
  92.             }
  93.             fclose(fp);
  94.             printf("File:\t%s Transfer Finished!\n", file_name);
  95.         }
  96.   
  97.         close(new_server_socket);
  98.     }
  99.   
  100.     close(server_socket);
  101.   
  102.     return 0;
  103. }

cli.c

  1. #include<netinet/in.h>
  2. #include<sys/types.h>
  3. #include<sys/socket.h>
  4. #include<stdio.h>
  5. #include<stdlib.h>
  6. #include<string.h>
  7.   
  8. #define PORT 5552
  9. #define BUFFER_SIZE 1024
  10. #define MAX_SIZE 512
  11.   
  12. int main(int argc, char **argv)
  13. {
  14.     if (argc != 2)
  15.     {
  16.         printf("IP error\n");
  17.         exit(1);
  18.     }
  19.     // 创建用于internet的流协议(TCP)类型socket,用client_socket代表客户端socket
  20.     int client_socket = socket(AF_INET, SOCK_STREAM, 0);
  21.     if (client_socket < 0)
  22.     {
  23.         printf("Create Socket Failed!\n");
  24.         exit(1);
  25.     }
  26.     // 设置一个socket地址结构server_addr,代表服务器的internet地址和端口
  27.     struct sockaddr_in server_addr;
  28.     memset(&server_addr,0, sizeof(server_addr));
  29.     server_addr.sin_family = AF_INET;
  30.   
  31.     // 服务器的IP地址来自程序的参数
  32.     if (inet_aton(argv[1], &server_addr.sin_addr) == 0)
  33.     {
  34.         printf("Server IP Address Error!\n");
  35.         exit(1);
  36.     }
  37.   
  38.     server_addr.sin_port = htons(PORT);
  39.     socklen_t server_addr_length = sizeof(server_addr);
  40.   
  41.     // 向服务器发起连接请求,连接成功后client_socket代表客户端和服务器端的一个socket连接
  42.     if (connect(client_socket, (struct sockaddr*)&server_addr, server_addr_length) < 0)
  43.     {
  44.         printf("Can Not Connect To %s!\n", argv[1]);
  45.         exit(1);
  46.     }
  47.   
  48.     char file_name[MAX_SIZE + 1];
  49.     memset(file_name,0, sizeof(file_name));
  50.     printf("Please Input T he File Name On Server.\t");
  51.     scanf("%s", file_name);
  52.   
  53.     char buffer[BUFFER_SIZE];
  54.     memset(buffer,0, sizeof(buffer));
  55.     strncpy(buffer, file_name, strlen(file_name) > BUFFER_SIZE ? BUFFER_SIZE : strlen(file_name));
  56.     // 向服务器发送buffer中的数据,此时buffer中存放的是客户端需要接收的文件的名字
  57.     send(client_socket, buffer, BUFFER_SIZE, 0);
  58.   
  59.     FILE *fp = fopen(file_name, "w");
  60.     if (fp == NULL)
  61.     {
  62.         printf("File:\t%s Can Not Open To Write!\n", file_name);
  63.         exit(1);
  64.     }
  65.   
  66.     // 从服务器端接收数据到buffer中
  67.     memset(buffer,0, sizeof(buffer));
  68.     int length = 0;
  69.     while(length = recv(client_socket, buffer, BUFFER_SIZE, 0))
  70.     {
  71.         if (length < 0)
  72.         {
  73.             printf("Recieve Data From Server %s Failed!\n", argv[1]);
  74.             break;
  75.         }
  76.   
  77.         int write_length = fwrite(buffer, sizeof(char), length, fp);
  78.         if (write_length < length)
  79.         {
  80.             printf("File:\t%s Write Failed!\n", file_name);
  81.             break;
  82.         }
  83.         memset(buffer,0, BUFFER_SIZE);
  84.     }
  85.   
  86.     printf("Recieve File:\t %s From Server[%s] Finished!\n", file_name, argv[1]);
  87.   
  88.     // 传输完毕,关闭socket
  89.     fclose(fp);
  90.     close(client_socket);
  91.     return 0;
  92.   
  93. }
  运行之后的截图:
  1. lwp@lwp-linux:~/Desktop$ ./cli 192.168.200.180
  2. Please Input T he File Name On Server. data
  3. Recieve File: liwenping From Server[192.168.200.180] Finished!
  1. lwp@lwp-linux:~/Desktop$ ./ser
  2. File:    data Transfer
这样我们就将服务端的data文件传输到了客户端。

阅读(3920) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~