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

所属分类: 软件编程 / C 语言 阅读数: 125
收藏 0 赞 0 分享

本文实例展示了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++入门学习中的基础知识,需要的朋友可以参考下
收藏 0 赞 0 分享

解析C++中多层派生时的构造函数及一些特殊形式

这篇文章主要介绍了解析C++中多层派生时的构造函数及一些特殊形式,特殊形式主要针对基类和子对象类型的构造函数内容,需要的朋友可以参考下
收藏 0 赞 0 分享

简单介绍C++编程中派生类的析构函数

这篇文章主要介绍了C++编程中派生类的析构函数,析构函数平时一般使用较少,需要的朋友可以参考下
收藏 0 赞 0 分享

深入解析C++中类的多重继承

这篇文章主要介绍了深入解析C++中类的多重继承,包括多重继承相关的二义性问题,需要的朋友可以参考下
收藏 0 赞 0 分享

详解C++中基类与派生类的转换以及虚基类

这篇文章主要介绍了详解C++中基类与派生类的转换以及虚基类,是C++入门学习中的基础知识,需要的朋友可以参考下
收藏 0 赞 0 分享

解析C++编程中的继承方面的运用

这篇文章主要介绍了解析C++编程中的继承方面的运用,是C++入门学习中的基础知识,需要的朋友可以参考下
收藏 0 赞 0 分享

详解C++编程的多态性概念

这篇文章主要介绍了C++编程的多态性概念,是C++入门学习中的基础知识,需要的朋友可以参考下
收藏 0 赞 0 分享

c++统计文件中字符个数代码汇总

本文给大家汇总介绍了3种使用C++实现统计文件中的字符个数的方法,非常的简单实用,有需要的小伙伴可以参考下。
收藏 0 赞 0 分享

详解C++编程中的虚函数

这篇文章主要介绍了详解C++编程中的虚函数,包括在什么情况下应当声明虚函数的相关讲解,需要的朋友可以参考下
收藏 0 赞 0 分享

C语言putenv()函数和getenv()函数的使用详解

这篇文章主要介绍了C语言putenv()函数和getenv()函数的使用详解,用来进行环境变量的相关操作,需要的朋友可以参考下
收藏 0 赞 0 分享
查看更多