gpt4 book ai didi

c++ - 通过套接字发送文件太慢

转载 作者:可可西里 更新时间:2023-11-01 09:29:55 24 4
gpt4 key购买 nike

我是新来的(我的第一个问题),有点新手,我从来没有上过编程课,所以...对于一些困惑的代码感到抱歉。

我制作了这个通过套接字发送(客户端)和接收(服务器)文件的程序,客户端每次循环读取和发送 1024 字节的文件,服务器接收它并将其写入文件。它工作正常,但问题是它非常慢。将文件从我的计算机发送到我的计算机所花费的时间与将文件发送到另一台计算机所花费的时间一样多,但仍然比预期花费更多的时间,例如,当我尝试通过 Skype 传输时,速度要快得多。有什么线索吗? (下面是我正在使用的代码)。

服务器:

// servrecvfile.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#undef UNICODE

#define WIN32_LEAN_AND_MEAN

#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>

// Need to link with Ws2_32.lib
#pragma comment (lib, "Ws2_32.lib")
// #pragma comment (lib, "Mswsock.lib")

#define DEFAULT_BUFLEN 65536
#define DEFAULT_PORT "8883"

typedef struct thread_args{
SOCKET ClientSocket;
int index;
} *MYDATA, PM;

MYDATA pDataArray[100];
DWORD WINAPI abc(void*);

int p=0;

int abz(){
return p;
}

void broadcast(MYDATA *fp, char *b, int index){
for(int i=0; i<=abz(); i++){
if(index != i)
send( fp[i]->ClientSocket, b, (int)strlen(b), 0 );
}
}

DWORD WINAPI abc(void* pVoid)
{
struct thread_args *fp;
fp = (struct thread_args *) pVoid;
long iResult;
int filesize;
unsigned char recvbuf[ DEFAULT_BUFLEN];
memset(recvbuf, 0, sizeof(recvbuf));
recv(fp->ClientSocket, (char*)recvbuf, DEFAULT_BUFLEN, 0);
FILE *abc = fopen(strtok ((char*)recvbuf,":"), "wb");
filesize = atoi(strtok (NULL,":"));
memset(recvbuf, 0, sizeof(recvbuf));
int perc=0;
int perc2=0;
int counter=0;
char a = '%';
do {
iResult = recv(fp->ClientSocket, (char*)recvbuf, DEFAULT_BUFLEN, 0);
if (iResult > 0) {
counter += fwrite (recvbuf , sizeof(char) , iResult , abc );
memset(recvbuf, 0, sizeof(recvbuf));
perc2 = ((counter*1.000)/filesize*1.000)*100;
if(perc2 != perc){
printf("%d%c\n", perc2, a);
perc = perc2;
}
}
else if (iResult == 0)
printf("Connection closing...\n");
else {
printf("recv failed with error: %d\n", WSAGetLastError());
closesocket(fp->ClientSocket);
fclose(abc);
WSACleanup();
ExitThread(1);
}
} while (iResult > 0);


fclose(abc);
ExitThread(-1);
}

int __cdecl main(void)
{
WSADATA wsaData;
int iResult;

SOCKET ListenSocket = INVALID_SOCKET;
SOCKET ClientSocket = INVALID_SOCKET;

struct addrinfo *result = NULL;
struct addrinfo hints;

int iSendResult;
char recvbuf[DEFAULT_BUFLEN];
int recvbuflen = DEFAULT_BUFLEN;


// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed with error: %d\n", iResult);
return 1;
}

ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;

// Resolve the server address and port
iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);
if ( iResult != 0 ) {
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
return 1;
}

// Create a SOCKET for connecting to server
ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
if (ListenSocket == INVALID_SOCKET) {
printf("socket failed with error: %ld\n", WSAGetLastError());
freeaddrinfo(result);
WSACleanup();
return 1;
}

// Setup the TCP listening socket
iResult = bind( ListenSocket, result->ai_addr, (int)result->ai_addrlen);
if (iResult == SOCKET_ERROR) {
printf("bind failed with error: %d\n", WSAGetLastError());
freeaddrinfo(result);
closesocket(ListenSocket);
WSACleanup();
return 1;
}

freeaddrinfo(result);

iResult = listen(ListenSocket, SOMAXCONN);
if (iResult == SOCKET_ERROR) {
printf("listen failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}

int i=0;
while(1){

// Accept a client socket
ClientSocket = accept(ListenSocket, NULL, NULL);
if (ClientSocket == INVALID_SOCKET) {
printf("accept failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
pDataArray[i] = (MYDATA) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof(PM));
pDataArray[i]->ClientSocket = ClientSocket;
pDataArray[i]->index = i;

CreateThread(
NULL, // default security attributes
0, // use default stack size
abc, // thread function name
pDataArray[i], // argument to thread function
0, // use default creation flags
NULL); // returns the thread identifier
p = i;
i++;
}

// No longer need server socket
closesocket(ListenSocket);

// Receive until the peer shuts down the connection
//char a[DEFAULT_BUFLEN];





// shutdown the connection since we're done
iResult = shutdown(ClientSocket, SD_SEND);
if (iResult == SOCKET_ERROR) {
printf("shutdown failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}

// cleanup
closesocket(ClientSocket);
WSACleanup();

return 0;
}

客户:

// sendfile.cpp : Defines the entry point for the console application.
//
#include "StdAfx.h"

#define WIN32_LEAN_AND_MEAN

#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>


// Need to link with Ws2_32.lib, Mswsock.lib, and Advapi32.lib
#pragma comment (lib, "Ws2_32.lib")
#pragma comment (lib, "Mswsock.lib")
#pragma comment (lib, "AdvApi32.lib")


#define DEFAULT_BUFLEN 65536
#define DEFAULT_PORT "8882"


int __cdecl main(int argc, char **argv)
{
WSADATA wsaData;
SOCKET ConnectSocket = INVALID_SOCKET;
struct addrinfo *result = NULL,
*ptr = NULL,
hints;
char *sendbuf = "this is a test";
char recvbuf[DEFAULT_BUFLEN];
int iResult;
int recvbuflen = DEFAULT_BUFLEN;

char linha[DEFAULT_BUFLEN];
char IP[20], porta[10];

FILE *fp1;
fp1 = fopen("config.txt", "r");
if(fp1 == NULL)
{
printf("Unable to find config.txt.\n");
exit(-1);
}
while( fgets(linha,DEFAULT_BUFLEN, fp1) !=NULL){
if(strstr(linha, "port="))
sscanf(linha, "port=%s", porta);
if(strstr(linha, "ip="))
sscanf(linha, "ip=%s", IP);
}

fclose(fp1);


char filenam[DEFAULT_BUFLEN];
printf("Insert file name: ");
scanf ("%s", filenam);
FILE *trans = fopen(filenam, "rb");

if(trans == NULL)
{
printf("File not found\n");
exit(-1);
}


// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed with error: %d\n", iResult);
return 1;
}

ZeroMemory( &hints, sizeof(hints) );
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;

// Resolve the server address and port
iResult = getaddrinfo(IP, porta, &hints, &result);
if ( iResult != 0 ) {
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
return 1;
}

// Attempt to connect to an address until one succeeds
for(ptr=result; ptr != NULL ;ptr=ptr->ai_next) {

// Create a SOCKET for connecting to server
ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype,
ptr->ai_protocol);
if (ConnectSocket == INVALID_SOCKET) {
printf("socket failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}

// Connect to server.
iResult = connect( ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
if (iResult == SOCKET_ERROR) {
closesocket(ConnectSocket);
ConnectSocket = INVALID_SOCKET;
continue;
}
break;
}

freeaddrinfo(result);

if (ConnectSocket == INVALID_SOCKET) {
printf("Unable to connect to server!\n");
WSACleanup();
return 1;
}



long lSize;

// obtain file size:
fseek (trans , 0 , SEEK_END);
lSize = ftell (trans);
rewind (trans);
char a = '%';
// allocate memory to contain the whole file:
memset(recvbuf, 0, sizeof(recvbuf));
unsigned char *linha2 = (unsigned char*) malloc (sizeof(unsigned char)* DEFAULT_BUFLEN);
//send(ConnectSocket, filenam, (int)strlen(filenam), 0 );
sprintf(filenam, "%s:%d", filenam, lSize);
printf("%d %d\n", send(ConnectSocket, filenam, (int)strlen(filenam), 0 ), lSize);
long counter=0;
long read;
int perc=0;
int perc2=0;
while(counter < lSize){
read = fread_s(linha2, DEFAULT_BUFLEN, sizeof(char), DEFAULT_BUFLEN, trans);
counter += send(ConnectSocket, (char*)linha2, read, 0);
perc2 = ((counter*1.000)/lSize*1.000)*100;
if(perc2 != perc){

printf("%d%c\n", perc2, a);
perc = perc2;
}

}






fclose(trans);
/*
do {
//memset(a, 0, sizeof(a));
iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
if ( iResult > 0 )
{
printf("%s", recvbuf);
memset(recvbuf, 0, sizeof(recvbuf));
}
else if ( iResult == 0 )
printf("Connection closed\n");
else
printf("recv failed with error: %d\n", WSAGetLastError());


} while( iResult > 0 ); */

// cleanup
closesocket(ConnectSocket);
WSACleanup();

return 0;
}

我在 Windows 7 上使用 visual studio 2010。

感谢任何帮助,如果这个问题的结构有任何问题,请告诉我。

最佳答案

为了通过套接字有效地发送文件数据,Windows 提供了 TransmitFile功能。

关于c++ - 通过套接字发送文件太慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15686738/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com