简单的C/S 程序 windows 版

很早写的了,感觉有点烂。


// server.cpp 服务器主要程序逻辑
#include <stdio.h>
#include <fstream>
#include <WinSock2.h>
#include <windows.h>
#include <ShareHeadFile.h>

#pragma comment(lib, "WS2_32.LIB") 

static DWORD __stdcall ThreadFunc(LPVOID lpParam);


int main()
{
     WSADATA wsaData;
     if (WSAStartup(MAKEWORD(2, 1), &wsaData) != 0)
     {
          printf("初始化WSADATA 失败!\n");
          return 0;
     }

     // 1. 创建SOCKET
     SOCKET sockServer = socket(AF_INET, SOCK_STREAM, 0);
     if (sockServer == SOCKET_ERROR)
     {
          printf("创建SOCKET 失败!\n");
          WSACleanup();
          return 0;
     }

     // 2. 绑定服务器主机地址
     sockaddr_in addrServer;
     addrServer.sin_family = AF_INET;
     addrServer.sin_port = htons(PORT);
     addrServer.sin_addr.S_un.S_addr = htonl(INADDR_ANY);

     // 绑定
     if (bind(sockServer, (sockaddr *)&addrServer, sizeof(addrServer)) == SOCKET_ERROR)
     {
          printf("绑定失败!\n");
          closesocket(sockServer);
          WSACleanup();
          return 0;
     }

     // 3. 监听
     listen(sockServer, 10);

     // 4. 连接通信
     while (1)
     {
          sockaddr_in addrClient;
          int nLen = sizeof(addrClient);
          SOCKET *pSockClient = new SOCKET;
          *pSockClient = accept(sockServer, (sockaddr *)&addrClient, &nLen);
          if (*pSockClient == SOCKET_ERROR)
          {
               printf("accept 失败!\n");
               break;
          }

          printf("客户端: %s 连接上来!\n", inet_ntoa(addrClient.sin_addr));
          CreateThread(NULL, 0, &ThreadFunc, pSockClient, 0, NULL);
     }

     closesocket(sockServer);
     WSACleanup();

     return 0;
}

// 线程函数
static DWORD __stdcall ThreadFunc(LPVOID lpParam)
{
     if (lpParam == NULL)
          return 0;

     SOCKET sockClient = *((SOCKET *)lpParam);
     delete (SOCKET *)lpParam, lpParam = NULL;

     char strFile[4096] = {0};
     recv(sockClient, strFile, 4096, 0);

     std::ifstream readFile(strFile, std::ios::binary);
     if (!readFile)
     {
          printf("打开文件: %s 失败!\n", strFile);
          closesocket(sockClient);
          return 0;
     }

     STRU_Package struPackage;
     int nSendCount = 0;
     int nDataPackageCount = 0;
     while (1)
     {
          if (readFile.eof())
          {
               printf("文件全部发送完毕。\n");
               break;
          }
          readFile.read(struPackage.arrData + 1, DATA_SIZE);
          struPackage.arrData[0] = (readFile.eof() ? 1 : 0);
          // 当前包中实际字节数
          struPackage.lDataLength = htonl((unsigned long)readFile.gcount());

          nDataPackageCount = (int)(sizeof(struPackage.lDataLength) + 1 + readFile.gcount());
          nSendCount = send(sockClient, (const char *)&struPackage,
               nDataPackageCount, 0);
          if (nSendCount < 0)
          {
               printf("发送失败...\n");
               break;
          }
     }
     readFile.close();
     closesocket(sockClient);

     return 0;
}



// 客户端主要程序代码

#include <stdio.h>
#include <WinSock2.h>
#include <fstream>
#include <ShareHeadFile.h>
#include <io.h>

#pragma comment(lib, "WS2_32.LIB")

int main()
{
#ifdef WIN32
       WSADATA wsaData;
     if (WSAStartup(MAKEWORD(2, 1), &wsaData) != 0)
     {
          printf("初始化WSADATA 失败!\n");
          return -1;
     }
#endif

     // 1. 创建SOCKET
     SOCKET sockClient = socket(AF_INET, SOCK_STREAM, 0);
     if (sockClient == SOCKET_ERROR)
     {
          printf("创建SOCKET 失败!\n");
          WSACleanup();
          return -2;
     }

     // 2. 准备服务器地址
     //fflush(stdin);
     char szServerIP[64] = {0};
     printf("输入服务器地址: ");
     scanf(" %s", szServerIP);

     sockaddr_in addrServer;
     addrServer.sin_family = AF_INET;
     addrServer.sin_port = htons(PORT);
     addrServer.sin_addr.S_un.S_addr = (inet_addr(szServerIP));

     // 3. 连接到服务器
     if (connect(sockClient, (const sockaddr *)&addrServer,
          sizeof(addrServer)) != 0)
     {
          printf("连接到服务器失败!\n");
          closesocket(sockClient);
          WSACleanup();
          return -3;
     }

     // 4. 与服务器通信
     char strFile[MAX_PATH] = {0};
     fflush(stdin);
     printf("输入文件名:");
     scanf(" %s", strFile);
     send(sockClient, strFile, strlen(strFile) + 1, 0);

     char *pCh = strrchr(strFile, '\\');
     (pCh == NULL) ? (pCh = strFile) : (++pCh);
     char strName[MAX_PATH] = "D:\\TestDir\\";
     strcat(strName, pCh);

     FILE *fp = fopen(strName, "wb");
     if (fp == NULL)
     {
          closesocket(sockClient);
          WSACleanup();
          return -4;
     }

     printf("开始文件。\n");
     STRU_Package struPackage;
     char arrRecvBuff[sizeof(STRU_Package)] = {0};
     unsigned long uIndex = 0;
     while (1)
     {
          int nRecvCount = 0;
          nRecvCount = recv(sockClient, arrRecvBuff + uIndex,
               sizeof(arrRecvBuff) - uIndex, 0);
          if (nRecvCount < 0)
          {
               printf("接收文件出错\n");
               break;
          }
          uIndex += nRecvCount;
          // 缓冲区中的数据连一个整数的个数都不到则需要继续recv
          if (uIndex < sizeof(struPackage.lDataLength))
               continue;
          // 前4个字符为数据的字符个数
          struPackage.lDataLength = ntohl(*((u_long *)arrRecvBuff));
          if (uIndex < sizeof(struPackage.lDataLength) + sizeof(char)
               + struPackage.lDataLength )
               continue;

          // 将数据写入文件
          size_t sizeWrite = 0;
          sizeWrite = fwrite(
               arrRecvBuff + (sizeof(struPackage.lDataLength) + sizeof(char)),
               struPackage.lDataLength, 1, fp);
          if (sizeWrite < 0)
               printf("数据写入错误\n");
          if (arrRecvBuff[sizeof(struPackage.lDataLength)])
          {
               printf("数据接收完成\n");
               break;
          }
          // 移动数据到首部
          int nUseSize = sizeof(struPackage.lDataLength) + sizeof(char) + struPackage.lDataLength;
          int nUnUseSize = uIndex - nUseSize;
          if (nUnUseSize > 0)
          {
               memmove(arrRecvBuff, arrRecvBuff + nUseSize, nUnUseSize);
               uIndex = nUnUseSize;
          }
          else
               uIndex = 0;
     }
     printf("文件接收完成。\n");

     fclose(fp), fp = NULL;
     closesocket(sockClient);
     WSACleanup();
     return 0;
}




  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值