Socket 实现非阻塞式多线程文件传输(jpg mov 等各种格式)

Socket 基础

非阻塞式TCP socket

实现文件传输

实测 传输5Mjpg , 30M的 NEF(单反原图以及 1G以上的mov文件,均正常接收

客户端可多开,服务器多线程实现服务器一对多

 

服务器部分:                                                   

#define _WINSOCK_DEPRECATED_NO_WARNINGS

#include <WinSock2.h>

#pragma comment(lib"ws2_32.lib")

#include <stdio.h>

#include <thread>

#define BUF_SIZE 1024

#include <iostream>

 

void connThread(SOCKET sock)

{

char chBuf[1024];

int nRes = 0;

std::FILEf;

errno_t err;

err = fopen_s(&f"G:\\qzher_3249.MOV""rb");

//err = fopen_s(&f, "G:\\qzher_3165.NEF", "rb");

//err = fopen_s(&f, "G:\\qzher_3052.jpg", "rb");

UINT64 nFileLen = 0;

if (err == 0)

{

fseek(f, 0L, SEEK_END);

nFileLen = ftell(f);

printf("文件大小为:%d 字节\n"nFileLen);

fseek(f, 0, SEEK_SET);

}

else

{

printf("The file   was not opened\n");

return;

}

 

UINT64 nRead = 0;

UINT64 nSendLen = 0;

 

clock_t startfinish;

double    dDuration = 0.0;

start = clock();

int i = 0;

while (true)

{

ZeroMemory(chBufBUF_SIZE);

 

if ((nFileLen – nSendLen)  >= BUF_SIZE )

{

nRead = fread(chBufsizeof(char), BUF_SIZEf);

//nRemainLen -= BUF_SIZE;

}

else  // 剩下的

{

if (nFileLen <= nSendLen)

{

break;

}

nRead = fread(chBufsizeof(char), nFileLen – nSendLenf);

//nSendLen = 0;

}

 

for (i = 0; i < nRead😉

{

nRes = send(sockchBuf + inReadi, 0);

if (0 < nRes)

{

nSendLen += nRes;

i += nRes;

}

else

{

i = 0;

}

}

 

if (0 == (nSendLen % 102400))

{

std::thread::id  id = std::this_thread::get_id();

std::cout << "线程" << id << "   已发送 " << nSendLen << " / " << nFileLen;

float dRadio = (float)(nSendLen * 100) / ((float)nFileLen);

std::cout << "\t" << dRadio << "%" << std::endl;

}

 

if (SOCKET_ERROR == nRes)

{

nRes = GetLastError();

if (WSAEWOULDBLOCK == nRes)

{

Sleep(1);

continue;

}

}

}

 

 

finish = clock();

dDuration = (double)(finish – start) / CLOCKS_PER_SEC;

printf("———trans finish—%f seconds\t"dDuration);

 

Sleep(1000);

 

shutdown(sockSD_SEND);

closesocket(sock);

if (f)

{

fclose(f);

printf(" exit\n");

}

}

 

 

int main()

{

WSADATA wsaData;

WSAStartup(MAKEWORD(2, 2), &wsaData);

SOCKET sockServer;

sockServer = socket(AF_INETSOCK_STREAMIPPROTO_TCP);

if (INVALID_SOCKET == sockServer)

{

WSACleanup();

return -1;

}

int mode = 1;

int nRes = 0;

nRes = ioctlsocket(sockServerFIONBIO, (u_long*)&mode);

if (SOCKET_ERROR == nRes)

{

closesocket(sockServer);

WSACleanup();

return -1;

}

SOCKADDR_IN  addrServ;

addrServ.sin_family = AF_INET;

addrServ.sin_port = htons(2345);

addrServ.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");

nRes = bind(sockServer, (sockaddr*)&addrServsizeof(sockaddr));

if (SOCKET_ERROR == nRes)

{

closesocket(sockServer);

WSACleanup();

return -1;

}

nRes = listen(sockServer, 5);

if (SOCKET_ERROR == nRes)

{

closesocket(sockServer);

WSACleanup();

return -1;

}

printf("————————————————\n");

printf("—————–服务器启动成功—————-\n");

printf("————————————————\n\n");

SOCKET sockClient;

SOCKADDR_IN addrClient;

int nFileLen = sizeof(SOCKADDR);

while (true)

{

sockClient = accept(sockServer, (sockaddr*)&addrClient, &nFileLen);

if (INVALID_SOCKET == sockClient)

{

nRes = WSAGetLastError();

if (WSAEWOULDBLOCK == nRes)

{

Sleep(100);

continue;

}

else

{

closesocket(sockServer);

WSACleanup();

return -1;

}

}

std::thread threadA(connThreadsockClient);

threadA.detach();

Sleep(600);

}

 

return 0;

}

 

 

 

 

青哲科技 qzher.com  致力于良心IT培训 深圳QQ群:326023167

 

 


服务器部分:                                                   

 

#define _WINSOCK_DEPRECATED_NO_WARNINGS

#include <WinSock2.h>

#pragma comment(lib"ws2_32.lib")

#include <stdio.h>  

#include <string.h>

#include <time.h>

 

#define BUF_SIZE  1024

int main()

{

WSAData wsaData;

int nRes = 0;

nRes = WSAStartup(MAKEWORD(2, 2), &wsaData);

SOCKET sockServer;

sockServer = socket(AF_INETSOCK_STREAMIPPROTO_TCP);

if (INVALID_SOCKET == sockServer)

{

WSACleanup();

return -1;

}

int nMode = 1;

nRes = ioctlsocket(sockServerFIONBIO, (u_long*)&nMode);

if (SOCKET_ERROR == nRes)

{

closesocket(sockServer);

WSACleanup();

return -1;

}

sockaddr_in addrServer;

addrServer.sin_family = AF_INET;

addrServer.sin_port = htons(2345);

addrServer.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");

int nLen = sizeof(sockaddr);

errno_t err;

FILE *f = nullptr;

struct tm tLocal;

time_t t = time(NULL);

localtime_s(&tLocal, &t);

 

char chName[24];

 

//sprintf_s(chName, "D:\\%d%d%d.jpg", tLocal.tm_hour, tLocal.tm_min, tLocal.tm_sec);

//sprintf_s(chName, "D:\\%d%d%d.NEF", tLocal.tm_hour, tLocal.tm_min, tLocal.tm_sec);

sprintf_s(chName"D:\\%d%d%d.mov"tLocal.tm_hourtLocal.tm_mintLocal.tm_sec);

 

err = fopen_s(&fchName"wb");

if (err != 0)

{

printf("The file   was not opened\n");

}

while (true)

{

nRes = connect(sockServer, (sockaddr*)&addrServersizeof(sockaddr));

if (SOCKET_ERROR == nRes)

{

nRes = WSAGetLastError();

if (WSAEWOULDBLOCK == nRes || WSAEINVAL == nRes)

{

Sleep(5);

continue;

}

else if (WSAEISCONN == nRes)

{

break;

}

else

{

closesocket(sockServer);

WSACleanup();

return 0;

}

}

}

 

unsigned int nRecvByte = 0;

 

char chBuf[BUF_SIZE];

printf("————————————————-\n");

printf("—————-客户端和服务器连接成功———-\n");

printf("————————————————-\n\n");

while (true)

{

ZeroMemory(chBufBUF_SIZE);

nRes = recv(sockServerchBufBUF_SIZE, 0);

if (SOCKET_ERROR == nRes)

{

nRes = GetLastError();

if (WSAEWOULDBLOCK == nRes)

{

Sleep(1);

continue;

}

else

{

break;

}

}

else if(0 >= nRes )

{

break;

Sleep(5);

continue;

}

 

nRecvByte += nRes;

fwrite(chBufsizeof(char), nResf);

if (nRecvByte% 102400)

{

printf("接收: %d 字节\n"nRecvByte);

fflush(f);

}

}

 

closesocket(sockServer);

WSACleanup();

if (f)

{

fflush(f);

Sleep(2000);

fclose(f);

}

printf("接收完成,退出\n"nRecvByte);

Sleep(2000);

return 0;

}

 

青哲科技 qzher.com  致力于良心IT培训 深圳QQ群:326023167

 


 

 

 

 

 

 

 

 

 

 

 

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注