如果将数据(buffer)尺寸设置为一个较大的值(如2048等)就会出现timeout的错误。在这种情形下更不用说传输一个大文件了,因此我们需要寻找一种解决方案。本文正是为此而展开。核心思想是:1.在PC端,打开文件,分块读取数据到buffer(比如每一块大小为2KB等)2.在PC端,每次读取数据到bufer后将buffer数据发送到socket3.数据经过网络连接传送到DSP端4.DSP端不断处理(暂存)ETH0接口收到的数据并发送响应5.在PC端,每次发送一个数据块之后等待来自DSP的响应,之后才发送下一块6.在PC端,不断发送数据块,直到整个文件数据发送完毕,最后关闭连接经过测试发现,将文件分成2048B(=2KB)大小的块进行发送是一个比较好的选择。每次发送2KB被DSP收到后立即被处理,然后DSP发回响应,表示已经收到这个数据。PC端收到应答后就知道刚才发给DSP的数据已经被接收了,可以发送下一块数据。为了让测试更加严谨,我们找来几个大小不同的文件,具体测试过程截图如下
一幅普通尺寸(1000*1000以下)的图片,30KB左右,处理时间不到1秒一幅稍大尺寸(1920*1080)的图片,不到1MB,处理时间1秒左右测试一个较大的文件,44.13MB大小,处理用时25秒左右测试一个更大的文件,191.82MB大小,处理用时103秒左右最后测试传输一张大尺寸照片,4k*3k分辨率,5.28MB大小,用时约3秒在CCS调试输出窗口的截图如下
对比一下发现,5次测试中都能正确收到全部数据。
这个测试表明,我们的流程设计是合理的。最后将PC端发送数据以及DSP端接收数据的代码贴上来以供参考。- // PC端:发送数据
- // fengyhack [url=home.php?mod=space&uid=72445]@[/url] 20150203
- #include <stdio.h>
- #include <time.h>
- #include <stdlib.h>
- #include "sockets.h"
- #pragma comment(lib,"ws2_32.lib")
- #pragma warning(disable:4996)
-
- const char *TARGET = "169.254.11.123";
- #define PORT 7
- #define TIMEOUT 1 /* second(s) */
-
- int main(void)
- {
- system("title Ethernet0 Transfer Test");
- system("color 2e");
- printf("Remote ( %s : %d )
", TARGET, PORT);
-
- char fileName[256] = { 0 };
- printf("Input filename:");
- scanf("%s", fileName);
- FILE* fp = fopen(fileName, "rb");
- if (fp == NULL)
- {
- printf("Failed to open file.
");
- goto leave;
- }
- long fsize = 0;
- fseek(fp, 0L, SEEK_END);
- fsize = ftell(fp);
- double kilo = 1.0*fsize / 1024.0;
- if (kilo >= 1024.0)
- {
- printf("File size: %.2fMB
", kilo/1024.0);
- }
- else
- {
- printf("File size: %.2fKB
", kilo);
- }
- const int unit = 2048;
- int loop = fsize / unit;
- int residue = fsize - loop*unit;
- char* data = (char*)malloc(unit + 1);
-
- struct in_addr dst;
- inet_pton(AF_INET, TARGET, &dst);
- unsigned short port = PORT;
- socketsStartup();
- SOCKET s = socket(AF_INET, SOCK_DGRAM, 0);
- if (s < 0)
- {
- printf("failed socket (%d)
", getError());
- goto leave;
- }
-
- struct sockaddr_in sin;
- sin.sin_family = AF_INET;
- sin.sin_addr.s_addr = 0;
-
- int status = 0;
- status = bind(s, (const struct sockaddr *) &sin, sizeof(sin));
- if (status< 0)
- {
- printf(" failed bind (%d)
", getError());
- goto leave;
- }
- sin.sin_addr = dst;
- sin.sin_port = htons(port);
-
- struct timeval timeout;
- timeout.tv_sec = TIMEOUT;
- timeout.tv_usec = 0;
-
- fd_set fds;
- int nr;
- char tmp[8] = { 0 };
-
- printf("<Start sending data>
");
-
- time_t time_start = time(0);
-
- for (int i = 1; i <= loop; ++i)
- {
- fread(data, unit, 1, fp);
- data[unit] = 0;
- status = sendto(s, data, strlen(data), 0, (const struct sockaddr *)&sin, sizeof(sin));
- if (status< 0)
- {
- printf("send failed (%d)
", getError());
- goto leave;
- }
-
- FD_ZERO(&fds);
- FD_SET(s, &fds);
-
- select(s + 1, &fds, NULL, NULL, &timeout);
- nr = recv(s, tmp, 8, 0);
-
- if (i % 64 == 0)
- {
- printf(".");
- if (i % 4096 == 0) printf(" (%4.1f%%)
", 100.0*i / loop);
- }
- }
- if (residue > 0)
- {
- fread(data, residue, 1, fp);
- data[residue] = 0;
- status = sendto(s, data, strlen(data), 0, (const struct sockaddr *)&sin, sizeof(sin));
- if ( status< 0)
- {
- printf("send failed (%d)
", getError());
- goto leave;
- }
-
- FD_ZERO(&fds);
- FD_SET(s, &fds);
-
- select(s + 1, &fds, NULL, NULL, &timeout);
- nr = recv(s, tmp, 8, 0);
- printf(" (100%%)
");
- }
- fclose(fp);
-
- printf("Finished transfer. Time = %d seconds
", (int)(time(0) - time_start));
-
- leave:
- if(s>=0) closesocket(s);
- if(data) free(data);
- socketsShutdown();
-
- system("pause");
- return 0;
- }
复制代码
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
一周热门 更多>