Windows网络编程之winsock实现文件传输示例

 更新时间:2014年08月14日 15:12:53   投稿:shichen2014  
这篇文章主要介绍了Windows网络编程之winsock实现文件传输示例,对于学习Windows网络程序设计来说具有很好的学习借鉴价值,需要的朋友可以参考下

本文实例展示了Windows网络编程中winsock实现文件传输的方法,对于进行Windows下的winsock网络编程有一定的借鉴参考价值。

该程序代码主要是基于TCP流协议的winsock网络文件传输示例,采用Windows下的C语言编写。可以实现传递任何格式文件的文件传输功能。

具体实现代码如下:

Server端代码如下:

/************************************************************************* 
  > File Name: Win_Server.c 
  > Author: SongLee 
 ************************************************************************/ 
 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <WinSock2.h> 
 
#define PORT 8087 
#define SERVER_IP "127.0.0.1" 
#define BUFFER_SIZE 1024 
#define FILE_NAME_MAX_SIZE 512 
#pragma comment(lib, "WS2_32") 
 
int main() 
{ 
  // 声明并初始化一个服务端(本地)的地址结构 
  sockaddr_in server_addr; 
  server_addr.sin_family = AF_INET; 
  server_addr.sin_addr.S_un.S_addr = INADDR_ANY; 
  server_addr.sin_port = htons(PORT); 
 
  // 初始化socket dll 
  WSADATA wsaData; 
  WORD socketVersion = MAKEWORD(2, 0); 
  if(WSAStartup(socketVersion, &wsaData) != 0) 
  { 
    printf("Init socket dll error!"); 
    exit(1); 
  } 
 
  // 创建socket 
  SOCKET m_Socket = socket(AF_INET, SOCK_STREAM, 0); 
    if (SOCKET_ERROR == m_Socket) 
    { 
      printf("Create Socket Error!"); 
    exit(1); 
    } 
 
  //绑定socket和服务端(本地)地址 
  if (SOCKET_ERROR == bind(m_Socket, (LPSOCKADDR)&server_addr, sizeof(server_addr))) 
  { 
    printf("Server Bind Failed: %d", WSAGetLastError()); 
    exit(1); 
  } 
 
  //监听 
  if (SOCKET_ERROR == listen(m_Socket, 10)) 
  { 
    printf("Server Listen Failed: %d", WSAGetLastError()); 
    exit(1); 
  } 
 
 
  while(1) 
  { 
    printf("Listening To Client...\n"); 
 
    sockaddr_in client_addr; 
    int client_addr_len = sizeof(client_addr); 
 
    SOCKET m_New_Socket = accept(m_Socket, (sockaddr *)&client_addr, &client_addr_len); 
    if (SOCKET_ERROR == m_New_Socket) 
    { 
      printf("Server Accept Failed: %d", WSAGetLastError()); 
      break; 
    } 
 
 char buffer[BUFFER_SIZE]; 
 memset(buffer, 0, BUFFER_SIZE); 
    if (recv(m_New_Socket, buffer, BUFFER_SIZE, 0) < 0) 
    { 
      printf("Server Receive Data Failed!"); 
      break; 
    } 
 
    char file_name[FILE_NAME_MAX_SIZE+1]; 
    memset(file_name, 0, 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, "rb"); //windows下是"rb",表示打开一个只读的二进制文件 
    if (NULL == fp) 
    { 
      printf("File: %s Not Found\n", file_name); 
    } 
        else 
    { 
      memset(buffer, 0, BUFFER_SIZE); 
      int length = 0; 
 
      while ((length = fread(buffer, sizeof(char), BUFFER_SIZE, fp)) > 0) 
      { 
        if (send(m_New_Socket, buffer, length, 0) < 0) 
        { 
          printf("Send File: %s Failed\n", file_name); 
          break; 
        } 
        memset(buffer, 0, BUFFER_SIZE); 
      } 
 
      fclose(fp); 
      printf("File: %s Transfer Successful!\n", file_name); 
    } 
    closesocket(m_New_Socket); 
  } 
 
  closesocket(m_Socket); 
  //释放winsock库 
  WSACleanup(); 
  return 0; 
} 

Client端代码如下:

/************************************************************************* 
  > File Name: Win_Client.c 
  > Author: SongLee 
 ************************************************************************/ 
 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <WinSock2.h> 
 
#define PORT 8087 
#define SERVER_IP "127.0.0.1" 
#define BUFFER_SIZE 1024 
#define FILE_NAME_MAX_SIZE 512 
#pragma comment(lib, "WS2_32") 
 
int main() 
{ 
  // 初始化socket dll 
  WSADATA wsaData; 
  WORD socketVersion = MAKEWORD(2, 0); 
  if(WSAStartup(socketVersion, &wsaData) != 0) 
  { 
    printf("Init socket dll error!"); 
    exit(1); 
  } 
 
  //创建socket 
  SOCKET c_Socket = socket(AF_INET, SOCK_STREAM, 0); 
  if (SOCKET_ERROR == c_Socket) 
  { 
    printf("Create Socket Error!"); 
    system("pause"); 
    exit(1); 
  } 
 
  //指定服务端的地址 
  sockaddr_in server_addr; 
  server_addr.sin_family = AF_INET; 
  server_addr.sin_addr.S_un.S_addr = inet_addr(SERVER_IP); 
  server_addr.sin_port = htons(PORT); 
 
  if (SOCKET_ERROR == connect(c_Socket, (LPSOCKADDR)&server_addr, sizeof(server_addr))) 
  { 
    printf("Can Not Connect To Server IP!\n"); 
    system("pause"); 
    exit(1); 
  } 
 
  //输入文件名 
  char file_name[FILE_NAME_MAX_SIZE+1]; 
  memset(file_name, 0, FILE_NAME_MAX_SIZE+1); 
  printf("Please Input File Name On Server: "); 
  scanf("%s", &file_name); 
 
  char buffer[BUFFER_SIZE]; 
  memset(buffer, 0, BUFFER_SIZE); 
  strncpy(buffer, file_name, strlen(file_name)>BUFFER_SIZE ? BUFFER_SIZE:strlen(file_name)); 
 
  //向服务器发送文件名 
  if(send(c_Socket, buffer, BUFFER_SIZE, 0) < 0) 
  { 
    printf("Send File Name Failed\n"); 
    system("pause"); 
    exit(1); 
  } 
 
  //打开文件,准备写入 
  FILE * fp = fopen(file_name, "wb"); //windows下是"wb",表示打开一个只写的二进制文件 
  if(NULL == fp) 
  { 
    printf("File: %s Can Not Open To Write\n", file_name); 
    system("pause"); 
    exit(1); 
  } 
  else 
  { 
    memset(buffer, 0, BUFFER_SIZE); 
    int length = 0; 
    while ((length = recv(c_Socket, buffer, BUFFER_SIZE, 0)) > 0) 
    { 
      if (fwrite(buffer, sizeof(char), length, fp) < length) 
      { 
        printf("File: %s Write Failed\n", file_name); 
        break; 
      } 
      memset(buffer, 0, BUFFER_SIZE); 
    } 
 
    printf("Receive File: %s From Server Successful!\n", file_name); 
  } 
 
  fclose(fp); 
  closesocket(c_Socket); 
   
  //释放winsock库 
  WSACleanup(); 
 
  system("pause"); 
  return 0; 
} 

程序中备有较为详尽的注释,相信大家不难理解。感兴趣的朋友可以根据自身需要对程序加以灵活改善,使其功能更加强大。

相关文章

  • Java C++ 算法题解leetcode669修剪二叉搜索树示例

    Java C++ 算法题解leetcode669修剪二叉搜索树示例

    这篇文章主要为大家介绍了Java C++ 算法题解leetcode669修剪二叉搜索树示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-09-09
  • 简单说说STL的内存管理

    简单说说STL的内存管理

    <STL 源码剖析>将其描述为空间配置器,理由是allocator可以将其它存储介质(例如硬盘)做为stl 容器的存储空间。由于内存是allocator管理的主要部分,因此,本文以STL内存管理为出发点介绍allocator
    2013-09-09
  • C语言之直接插入排序算法的方法

    C语言之直接插入排序算法的方法

    这篇文章主要为大家介绍了C语言直接插入排序算法的方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2021-12-12
  • C++使用模板实现单链表

    C++使用模板实现单链表

    这篇文章主要为大家详细介绍了C++使用模板实现单链表,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-12-12
  • 带头结点的链表的基本操作(超详细)

    带头结点的链表的基本操作(超详细)

    链表是一种动态分配空间的存储结构,能更有效地利用存储空间,通过对单链表基本操作的代码实现,我深刻领悟到以“指针”指示元素的后继,在插入或删除元素时不需要移动元素
    2023-07-07
  • C语言实现电话簿管理系统

    C语言实现电话簿管理系统

    这篇文章主要为大家详细介绍了C语言实现电话簿管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-12-12
  • C语言实现系统关机注销功能

    C语言实现系统关机注销功能

    这篇文章主要为大家详细介绍了C语言实现系统关机注销功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-02-02
  • C语言实现火车订票系统

    C语言实现火车订票系统

    这篇文章主要为大家详细介绍了C语言实现火车订票系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-08-08
  • C语言实现学生选课系统

    C语言实现学生选课系统

    这篇文章主要为大家详细介绍了C语言实现学生选课系统,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-02-02
  • visual studio code 配置C++开发环境的教程详解 (windows 开发环境)

    visual studio code 配置C++开发环境的教程详解 (windows 开发环境)

    这篇文章主要介绍了 windows 开发环境下visual studio code 配置C++开发环境的图文教程,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-03-03

最新评论