通过套接字发送图片(发送func)在c + +,但不要收回完整(Windows)!

我正在从客户端发送数据到服务器,但图片没有收到完整。

客户代码:

FILE *fr = fopen(tmppicsend, "rb"); char* buffer; buffer = (char*) malloc(sizeof(char)*size); fread(buffer, size, 1, fr); send_len_pic = send( m_socket_pic, buffer, size, 0 ); recv( m_socket_pic, rec_end_check, 32, 0 ); fclose(fr); free(buffer); 

服务器代码:

 FILE *fw = fopen(fname, "wb"); char* buffer; buffer = (char*) malloc(sizeof(char)*size); int rec_len = recv( current_client, buffer, size, 0 ); buffer[size]='\0'; fwrite(buffer, size, 1, fw); size -= size; free(buffer); fclose(fw); 

configuration套接字

 WSADATA wsaData_pic; SOCKET m_socket_pic; SOCKET m_backup_pic; sockaddr_in con_pic; // Initialize Winsock. int iResult = WSAStartup( MAKEWORD(2,2), &wsaData_pic ); if ( iResult != NO_ERROR ){ //printf("Error at WSAStartup()\n"); } // Create a socket. m_socket_pic = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP ); if ( m_socket_pic == INVALID_SOCKET ) { //printf( "Error at socket(): %ld\n", WSAGetLastError() ); //WSACleanup(); } m_backup_pic = m_socket_pic; // Connect to a server. con_pic.sin_family = AF_INET; con_pic.sin_addr.s_addr = inet_addr( ip ); con_pic.sin_port = htons( 2200 ); if ( connect( m_backup_pic, (SOCKADDR*) &con_pic, sizeof(con_pic) ) == SOCKET_ERROR) { //printf( "Failed to connect.\n" ); //WSACleanup(); }else { m_socket_pic=m_backup_pic; } } 

当我比较这些图片时,我看到序列号包中的错误(包没有定期接收)。 图片(从客户端和服务器图片)是相同的大小。 我想发送JPEG图片。

请帮助我,坦克。

Solutions Collecting From Web of "通过套接字发送图片(发送func)在c + +,但不要收回完整(Windows)!"

你正在犯一般的错误。 你不能假设recv()填充缓冲区。 您必须循环,直到获得所需的所有数据,并且必须使用recv()返回的计数值。

你怎么知道在服务器端接收的数据的大小? 您应该在服务器和客户端之间建立某种协议(由您自己定义)。 最简单的方法是首先发送uint64_t(8字节),这将保存图片大小,然后发送数据本身。 然后在服务器读取前8个字节后 – 它会知道有多少数据的期望。 然后,您只需重复recv()调用,直到获取客户端发送的所有数据。 在服务器端使用select()是一个好主意,等待下一个数据部分可用。 顺便说一句,如果你试图发送的图片足够大(在大多数情况下,它是真实的),它通过部分tcp或udp连接发送,而不是一个大件。 而且它是不可预知的(硬件决定它)有多大或者多少会被发送。 所以你绝对应该准备重复调用recv()来接收客户端发送给服务器的所有数据。

我想这是因为你发送的数据量很大,因为当你通过网络发送大包时,底层会把这个大包分成小包,然后通过网络发送这些包。

所以当你收到这些数据包时,这些数据包的顺序可能会改变,这就是为什么你正在接收相同的数据大小,但是图像是不正确的。

我会给你一个快速的解决方案,你可以尝试,

把你的文件分成小数组,可以说每个数组是1024字节,先发送这些数组的计数,然后开始发送第一个数组(1024字节),然后等待另一侧的确认,重复,直到你发送全部数据。

你可以在没有确认的情况下做,但是在每次发送之间留下一段时间。

你有没有尝试将图像缓冲区转换为base64,将其发送到您的代码的接收器部分,然后取消基地和malloc它?

以上的方式是我们的截图程序如何工作(远程管理),它的作品就像一个魅力..

客户端代码

  /* * Send size of the file first. */ n = sizeof(filesize); r = send(m_socket_pic, &filesize, n); if (r != n) { printf("error sending %d bytes\n", n); } /* * Now send the file. */ n = filesize; while (n > 0) { r = send(m_socket_pic, buffer, n, 0); buffer += r; n -= r; } 

服务器代码

  /* * Recv size of the file first. */ n = sizeof(filesize); r = recv(current_client, &filefsize, n); if (r != n) { printf("error receiving %d bytes\n", n); } /* * Now recv the file. */ n = filesize; while (n > 0) { r = recv(current_client, buffer, n, 0); buffer += r; n -= r; } 

谢谢大家,

问题是,通过套接字发送大文件。

我有很多方法测试,但没有回答问题。

据了解,我应该使用循环发送拆分数据。

最好的分割大小是512或1500,并且在recv()函数中有很大的问题,这个函数比send()函数慢。当我在循环块中使用Sleep(1000)时,减少了损坏的照片的数量。

我有很多尝试回答。

这个问题的最佳答案是:

将客户端与服务器同步以发送流。

因为recv()函数比send()函数慢,客户端发送服务器能够接收的数据量。


客户代码:

 char* bufferCMP; bufferCMP = (char*)malloc(sizeof(char) * size); p_file = fopen(tmppicsend,"rb"); fread(bufferCMP, 1, size , p_file); fclose(p_file); int chunkcount = size / DEFAULT_BUFLEN; int lastchunksize = size - (chunkcount * DEFAULT_BUFLEN); int fileoffset=0; //Sending Actual Chunks while (chunkcount > 0) { iResult = send( m_socket_pic, bufferCMP + (fileoffset * DEFAULT_BUFLEN) , DEFAULT_BUFLEN , 0 ); fileoffset++; chunkcount--; if (iResult != DEFAULT_BUFLEN) { //printf("Sending Buffer size <> Default buffer length ::: %d\n",WSAGetLastError()); } else { //printf("Sending Buffer size = %d \n", iResult); } } //Sending last Chunk iResult = send( m_socket_pic, bufferCMP + (fileoffset * DEFAULT_BUFLEN) , lastchunksize , 0 ); 

服务器代码:

 int FileCounter=0; bool flg=true; char * fileComplete; char * filesizeBuffer; FILE *temp; int iResult; int receiveBuffer = 0; int desiredRecBuffer = size ; //int desiredRecBuffer = DEFAULT_BUFLEN ; fileComplete = (char*) malloc (sizeof(char)* size ); while (desiredRecBuffer > 0) { iResult = recv( current_client, fileComplete + receiveBuffer , desiredRecBuffer , 0 ); //iResult = recv( ClientSocket, fileComplete + receiveBuffer , fileSize , 0 ); if (iResult < 1) { //printf("Reveive Buffer Error %d \n", WSAGetLastError()); } else { receiveBuffer += iResult; desiredRecBuffer = size - receiveBuffer ; //printf("Reveived Data size : %d \n", iResult); } } FILE *File = fopen(fname, "wb"); fwrite(fileComplete,1, size , File); //flg = true; free(fileComplete); fclose(File);