当前位置:网站首页>An example of network communication based on TCP / IP protocol -- file transmission
An example of network communication based on TCP / IP protocol -- file transmission
2022-04-23 08:19:00 【Ott_ Glodon】
One 、 Server code :MyServer.cpp
// MyServer.cpp : Defines the entry point for the console application .
//
#include "stdafx.h"
#include <iostream>
using namespace std;
#include<stdlib.h>
#include<winsock2.h>// Reference header file
#pragma comment(lib,"ws2_32.lib")// Reference library file
// maximum connection
#define g_MaxConnect 20
int g_Connect = 0;
struct sock_params
{
SOCKET hsock;
int nSockIndex;
};
// Thread implementation function
DWORD WINAPI threadpro(LPVOID pParam)
{
sock_params* sockPam = (sock_params*)pParam;
SOCKET hsock = sockPam->hsock;
int nSockIndex = sockPam->nSockIndex;
char aIndex[4];
_itoa_s(nSockIndex, aIndex, 10);
char buffer[1024];
char sendBuffer[1024];
if(hsock != INVALID_SOCKET)
{
cout<<" client "<< nSockIndex << " Join the server !" <<endl;
}
// Set the receive buffer size
int nRecvBufLen = 1024* 1024; // The default setting is 1024K
int nStaus = setsockopt(hsock ,SOL_SOCKET,SO_RCVBUF,(const char*)&nRecvBufLen,sizeof(int));
if (nStaus == SOCKET_ERROR)
{
hcDebugLog(_T("ZLY: Failed to set receive buffer size !"));
}
// Set the send buffer size
int nSendBufLen = 1024* 1024; // The default setting is 1024K
nStaus = setsockopt(hsock ,SOL_SOCKET,SO_SNDBUF,(const char*)&nSendBufLen,sizeof(int));
if (nStaus == SOCKET_ERROR)
{
hcDebugLog(_T("ZLY: Failed to set send buffer size !"));
}
// Circularly receive the contents of the sent file
int nErrorNum = 0;
while (1)
{
// The server receives the file name data
FileName fn;
memset(&fn, 0, sizeof(FileName));
int nRecvSize = recv(clientSocket, (char*)&fn, sizeof(fn), 0);
if (sizeof(fn) != nRecvSize)
{
if (nRecvSize != 0 && nErrorNum <= MAX_ERROR_NUM)
{
printf(" Failed to receive file name ! Error code :%d\n", WSAGetLastError());
nErrorNum++;
continue;
}
else
{
break;
}
}
char chPath[_MAX_PATH];
memset(chPath, 0, sizeof(char)*_MAX_PATH);
strcpy_s(chPath, sizeof(chPath), fn.serverDir);
int len = strlen(chPath);
if (chPath[len - 1] != '\\')
{
chPath[len] = '\\';
len++;
}
strcat_s(chPath, fn.dir);
len = strlen(chPath);
if (chPath[len - 1] != '\\')
{
chPath[len] = '\\';
len++;
}
// Create the corresponding directory
g_lock.Lock();
CreateDir(chPath);
g_lock.UnLock();
strcat_s(chPath, fn.Fname);
// create a file
FILE* fp = NULL;
errno_t err = fopen_s(&fp, chPath, "wb");
if (err != 0)
{
printf(" Failed to create file :%s, Error code :%d\n", chPath, GetLastError());
continue;
}
// The length of the file received by the server
long long nSize;
nRecvSize = recv(clientSocket, (char*)&nSize, sizeof(nSize), 0);
if (sizeof(nSize) != nRecvSize)
{
if (fp)
{
fclose(fp);
fp = NULL;
}
if (nRecvSize != 0 && nErrorNum <= MAX_ERROR_NUM)
{
printf(" Failed to receive file length ! Error code :%d\n", WSAGetLastError());
nErrorNum++;
continue;
}
else
{
break;
}
}
// Circular acceptance of file content
int num;
char buff[MAX_PACK_SIZE];
while (nSize > 0)
{
if (nSize >= MAX_PACK_SIZE)
{
num = recv(clientSocket, buff, MAX_PACK_SIZE, 0);
}
else
{
num = recv(clientSocket, buff, nSize, 0);
}
fwrite(buff, (int)num, 1, fp);
nSize -= num;
memset(buff, 0, sizeof(char)*MAX_PACK_SIZE); // take buff Empty
}
// Close file
if (fp)
{
fclose(fp);
fp = NULL;
}
// Send file acceptance success status
int nRecvStatus = 0;
send(clientSocket, (char*)&nRecvStatus, sizeof(int), 0);
}
return 0;
}
// The main function
void main()
{
WSADATA wsd;// Definition WSADATA object
WSAStartup(MAKEWORD(2,2),&wsd);
SOCKET m_SockServer;
sockaddr_in serveraddr;
sockaddr_in serveraddrfrom;
SOCKET m_Server[g_MaxConnect];
serveraddr.sin_family = AF_INET;// Set the server address
serveraddr.sin_port = htons(4600);// Set the port number
serveraddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
m_SockServer = socket(AF_INET,SOCK_STREAM,0);
int nStatus = bind(m_SockServer,(sockaddr*)&serveraddr,sizeof(serveraddr));
if (nStatus == 0)
{
cout << " Server started successfully !" <<endl;
}
else
{
cout << " Failed to start the server !" <<endl;
return;
}
int iLisRet = 0;
int len = sizeof(sockaddr);
while(1)
{
iLisRet = listen(m_SockServer,0);// monitor
m_Server[g_Connect] = accept(m_SockServer,(sockaddr*)&serveraddrfrom,&len);
// Agree to connect
if(m_Server[g_Connect] != INVALID_SOCKET)
{
if(g_Connect > g_MaxConnect-1)
{
char WarnBuf[50]=" Number of client connections : Transfinite !";
int ires = send(m_Server[g_Connect],WarnBuf,sizeof(WarnBuf),0);
}
else
{
char cIndex[4];
_itoa_s(g_Connect, cIndex, 10);
char buf[50]=" Your server ID: ";
strcat_s(buf, cIndex);
int ires = send(m_Server[g_Connect],buf,sizeof(buf),0);// Send characters past
//cout << buf <<endl;
HANDLE m_Handel; // Thread handle
DWORD nThreadId=0; // Threads ID
sock_params sockPam;
sockPam.hsock = m_Server[g_Connect];
sockPam.nSockIndex = g_Connect;
m_Handel = (HANDLE)::CreateThread(NULL,0,threadpro,&sockPam,0,&nThreadId);
CloseHandle(m_Handel);
}
++g_Connect;
}
}
WSACleanup();
}
Two 、 client :MyClient.cpp
// MyClient.cpp : Defines the entry point for the console application .
//
#include "stdafx.h"
#include<iostream>
using namespace std;
#include<stdlib.h>
#include<stdio.h>
#include"winsock2.h"
#include<time.h>
#pragma comment(lib,"ws2_32.lib")
void main()
{
WSADATA wsd;// Definition WSADATA object
WSAStartup(MAKEWORD(2,2),&wsd);
SOCKET m_SockClient;
sockaddr_in clientaddr;
clientaddr.sin_family = AF_INET; // Set the server address
clientaddr.sin_port = htons(4600); // Set the server port number
clientaddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
m_SockClient = socket(AF_INET,SOCK_STREAM,0);
if (m_SockClient == INVALID_SOCKET)
{
printf("Sock initialization failed : %d\n", WSAGetLastError());
WSACleanup();
return ;
}
// Get the size of sending buffer and receiving buffer
{
int optlen = 0;
int optval = 0;
optlen = sizeof(optval);
getsockopt(m_SockClient, SOL_SOCKET, SO_SNDBUF, (char*)&optval, &optlen);
printf("send buf len is %d\n",optval); //64 position Default send buffer 64k
getsockopt(m_SockClient, SOL_SOCKET, SO_RCVBUF, (char*)&optval, &optlen);
printf("Recv buf len is %d\n",optval); //64 position Default receive buffer 64k
}
// Set the receive buffer size
int nRecvBufLen = 1024* 1024; // The default setting is 1024K
int nStaus = setsockopt(pSocketData->clientSocket,SOL_SOCKET,SO_RCVBUF,(const char*)&nRecvBufLen,sizeof(int));
if (nStaus == SOCKET_ERROR)
{
hcDebugLog(_T("ZLY: Failed to set receive buffer size !"));
}
// Set the send buffer size
int nSendBufLen = 1024* 1024; // The default setting is 1024K
nStaus = setsockopt(pSocketData->clientSocket,SOL_SOCKET,SO_SNDBUF,(const char*)&nSendBufLen,sizeof(int));
if (nStaus == SOCKET_ERROR)
{
hcDebugLog(_T("ZLY: Failed to set send buffer size !"));
}
int nSuccess = connect(m_SockClient,(sockaddr*)&clientaddr,sizeof(clientaddr));// Connection timeout
if (nSuccess == 0)
{
cout<<" Successfully connected to the server !"<<endl;
}
else
{
cout<<" Failed to connect to server !"<<endl;
return;
}
char buffer[1024];
char inBuf[1024];
int num = 0;
num = recv(m_SockClient,buffer,1024,0);// Blocking
if(num > 0)
{
cout << /*"Receive from server:"<<*/ buffer<<endl;
char* pResult = strstr(buffer, " Transfinite ");
if (pResult != NULL)
{
cout<<" The number of server connections exceeds the limit , Unavailable !"<<endl;
system("pause");
return;
}
// Pass file name
char filename[256];
FILE* m_fp;
errno_t err = fopen_s(&m_fp, filename, "rb");
if (err != 0)
{
strlog.Format(_T(" file “%s” Open the failure , Error code :0x%X"), filename, GetLastError());
return -1;
}
// Send file name
if (sizeof(filename) != send(m_sock, &filename, sizeof(filename), 0))
{
strLog.Format(_T(" file “%s” Failed to send file name , Error code :%d."), (LPCTSTR)CString(m_fn.Fname), WSAGetLastError());
cout << strLog <<endl;
fclose(m_fp);
m_fp = NULL;
return -1;
}
fseek(m_fp, 0, SEEK_END);
long long nSize = ftell(m_fp);
fseek(m_fp, 0, SEEK_SET);
// Get file length , Send file length ( abandoned )
if (sizeof(nSize) != send(m_sock, (char*)&nSize, sizeof(nSize), 0))
{
printf(_T(" Failed to send file length , Error code :%d."), WSAGetLastError());
fclose(m_fp);
m_fp = NULL;
return -1;
}
// Send a file
/* Sending multiple files in a loop seems to make an error HANDLE hFile = CreateFile(lpszFilePath,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0); TransmitFile(m_Socket,hFile,0,TRANS_FILE_LENGTH,NULL,NULL,TF_DISCONNECT); CloseHandle(hFile); */
// Loop the file
size_t nNum;
while (1)
{
nNum = fread(m_temp, 1, 1024*500, m_fp);
if (nNum == 0)
break;
if (nNum != send(m_sock, m_temp, (int)nNum, 0))
{
strLog.Format(_T(" file “%s” Failed to send file data , Error code :%d."), (LPCTSTR)CString(m_fn.Fname), WSAGetLastError());
fclose(m_fp);
m_fp = NULL;
return -1;
}
memset(m_temp, 0, sizeof(char)*1024*500);
}
// Close file
fclose(m_fp);
m_fp = NULL;
// Receive the data fed back by the server
int recv_len = recv(m_SockClient,buffer,1024,0);
if(recv_len>=0)
{
cout<< buffer <<endl;
}
}
}
版权声明
本文为[Ott_ Glodon]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204230714487792.html
边栏推荐
- [go] common concurrency model [generic version]
- sql 使用过的查询语句
- C outputs a two-dimensional array with the following characteristics.
- Common regular expressions
- 万物互联下如何对设备进行加密
- 如何在SQL Server中导入excel数据,2019版
- Talk about the basic but not simple stock data
- Kubernetes in browser and IDE | interactive learning platform killercoda
- 396. Rotate Function
- 情境领导者-第七章、解决绩效问题
猜你喜欢

【Appium】测试时遇到手机内嵌H5页面的切换问题

一键清理项目下pycharm和Jupyter缓存文件

ASAN 极简原理

Search the complete navigation program source code

Weekly leetcode - 06 array topics 7 ~ 739 ~ 50 ~ offer 62 ~ 26 ~ 189 ~ 9

Qt读写XML文件

Comparison of indoor positioning methods of several intelligent robots

LeetCode簡單題之計算字符串的數字和

The third divisor of leetcode simple question
![[untitled]](/img/bb/213d95b60651dfeadb239a70507506.png)
[untitled]
随机推荐
[effective go Chinese translation] part I
输入/输出系统
一个没啥L用,但可以装X的IDEA插件
多目视觉SLAM
Qt读写XML文件
Ansible Automation Operation and Maintenance details (ⅰ) Installation and Deployment, Parameter use, list Management, Profile Parameters and user level ansible operating environment Construction
怎么读书读论文
synchronized 实现原理
LeetCode简单题之计算字符串的数字和
Usage of databinding
One click cleanup of pycharm and jupyter cache files under the project
[Effective Go 中文翻译] 第一篇
[Effective Go 中文翻译]函数篇
Planification du mouvement du manipulateur dans l'assemblage 3c
利用Js实现一个千分位
C outputs a two-dimensional array with the following characteristics.
PyQt5开发之QTableWidget表头自定义与美化(附源代码下载)
My heart's broken! A woman's circle of friends envied others for paying wages on time and was fired. Even her colleagues who liked her were fired together
LeetCoed18. Sum of four numbers
The third divisor of leetcode simple question