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; 
} 

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

相关文章

  • C++实现简单贪吃蛇游戏

    C++实现简单贪吃蛇游戏

    这篇文章主要为大家详细介绍了C++实现简单贪吃蛇游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-03-03
  • C语言实现简易通讯录完整流程

    C语言实现简易通讯录完整流程

    这篇文章主要为大家介绍了C语言实现简易通讯录的完整流程,每个环节都有完整代码,有需要的朋友可以借鉴参考下,希望能够有所帮助
    2022-02-02
  • C++实现LeetCode(33.在旋转有序数组中搜索)

    C++实现LeetCode(33.在旋转有序数组中搜索)

    这篇文章主要介绍了C++实现LeetCode(33.在旋转有序数组中搜索),本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-07-07
  • C++ opencv利用grabCut算法实现抠图示例

    C++ opencv利用grabCut算法实现抠图示例

    这篇文章主要为大家介绍了C++ opencv利用grabCut算法实现抠图的代码示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-05-05
  • Windows上使用vs编译fdk-aac的教程详解

    Windows上使用vs编译fdk-aac的教程详解

    有时需要在Windows上用到fdk-aac,fdk-aac是源码是cmake的,可以直接转成vs项目,下面就跟随小编一起学习一下如何在Windows上使用vs编译fdk-aac吧
    2023-11-11
  • C++简单五子棋的AI设计实现

    C++简单五子棋的AI设计实现

    这篇文章主要为大家详细介绍了C++简单五子棋的AI设计实现,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-09-09
  • Opencv二帧差法检测运动目标与提取轮廓

    Opencv二帧差法检测运动目标与提取轮廓

    这篇文章主要为大家详细介绍了Opencv使用二帧差法检测运动目标与提取轮廓,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-03-03
  • Qt实现图片移动实例(图文教程)

    Qt实现图片移动实例(图文教程)

    这学期实训的时候用MFC做过一个飞机大战,很无聊的东西,一直想用Qt做一个;首先需要解决的问题是图片的移动,怎么说飞机啊子弹啊都是动着的,图片当然要跑起来,感兴趣的你可不要走开啊
    2013-01-01
  • c++之移动构造函数或者移动赋值运算符的作用详解

    c++之移动构造函数或者移动赋值运算符的作用详解

    文章介绍了移动构造函数和移动赋值运算符的核心作用,它们通过资源管理权转移的方式实现对象的构造,减少内存拷贝的开销,移动构造函数的参数一定是一个右值引用
    2025-03-03
  • 详细了解C语言二叉树的建立与遍历

    详细了解C语言二叉树的建立与遍历

    这篇文章主要介绍了C中二叉树的建立和各种遍历实例代码,涉及树节点的定义,后序遍历,层序遍历,深度优先和广度优先等相关内容,具有一定借鉴价值,需要的朋友可以参考下
    2021-07-07

最新评论