TCP传输图片的问题

HANKER131523 2017-11-27 03:44:07
想要在两台电脑间用TCP传输图片,自己写了vs2015个控制台程序测试(我用的是一个700多k的jpg图片测试的),发现有问题,现将问题、部分测试结果和代码陈述如下:
问题:
(1)包尾对不上;
(2)图片传输过去后,上面十分之一左右正常,下面就不正常了;
已做的测试的结果:
(1)图片不加包头和包尾,可以正确传输;
(2)用客户端的解包方法在服务器端自己解包,完全正常,但是在客户端,就出问题了;
望大神多多指教问题所在,谢谢了
代码:
Server:

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

#include "stdafx.h"
#include <winsock2.h>
#include <ws2tcpip.h>
#include <assert.h>
#pragma comment(lib, "ws2_32.lib")

#define BUFFER_SIZE 1*1024*1024

void package_head(int type, int length, int seq, char *head);
void package_tail(char *tail);
void pack(int type, int length, int seq, char *pic, char *pack);
void unpack(char *in, int *type, int *length, int *seq, char *out);

int main()
{
FILE *out;
char *unpack_buffer = new char[BUFFER_SIZE];
//char *recv_buffer = new char[20 + BUFFER_SIZE + 8];
int *type_p = new int(0);
int *length_p = new int(0);
int *seq_p = new int(0);

WORD wVersionRequested;
WSADATA wsaData;
int err;

FILE *fp;
int length = 0;
int pic_type = 1; //jpg
int seq = 0;
int freadlength = 0;
char* buffer = new char[BUFFER_SIZE];
char* send_buffer = new char[32 + BUFFER_SIZE + 8];

wVersionRequested = MAKEWORD(1, 1);
err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0) {
perror("WSAStartup() Error!");
Sleep(2000);
return 0;
}
if (LOBYTE(wsaData.wVersion) != 1 ||
HIBYTE(wsaData.wVersion) != 1) {
WSACleanup();
perror("wsaData.wVersion Error!");
Sleep(2000);
return 0;
}

SOCKET sockRrv = socket(AF_INET, SOCK_STREAM, 0);
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr = htons(INADDR_ANY);
addrSrv.sin_port = htons(6000);
addrSrv.sin_family = AF_INET;
bind(sockRrv, (SOCKADDR *)&addrSrv, sizeof(sockaddr));
listen(sockRrv, 5);
SOCKADDR_IN addrClient;
int len = sizeof(sockaddr);

err = fopen_s(&fp, "1.jpg", "rb");
if (err != 0) {
perror("fopen_s.., 1.jpg, .. Error");
Sleep(2000);
return 0;
}

err = fopen_s(&out, "2.jpg", "wb");
if (err != 0) {
perror("fopen_s.., 2.jpg, .. Error");
Sleep(2000);
return 0;
}

fseek(fp, 0, SEEK_END);
length = ftell(fp);

rewind(fp);
freadlength = fread(buffer, 1, length, fp);
assert(freadlength == length);

if (length != freadlength) {
perror("length != freadlength");
Sleep(2000);
return 0;
}

char length_c[8];
int a = 0;

_itoa_s(length, length_c, 10);
a = atoi(length_c);

printf("a is %d %d", a, length);

int i = 0;

while (1) {

SOCKET sockConn = accept(sockRrv, (SOCKADDR *)&addrClient, &len);
printf("start transferring...\n");

char sendBuffer[100];
char recvBuffer[100] = "over";
while(i < 1){
char IPdotdec[20];
inet_ntop(AF_INET, &addrClient.sin_addr, IPdotdec, 16);
//sprintf_s(sendBuffer, "welcome %s to wwww.baidu.com", IPdotdec);
sprintf_s(sendBuffer, "%d server send", i);

//send(sockConn, sendBuffer, strlen(sendBuffer) + 1, 0);
pack(pic_type, length, seq, buffer, send_buffer);

int a;
int b = 1;

send(sockConn, send_buffer, 32 + BUFFER_SIZE + 8, 0);

recv(sockConn, recvBuffer, 100, 0);

printf("%s\n", recvBuffer);
i++;
printf("seq is %d\n", seq);
seq++;

unpack(send_buffer, type_p, length_p, seq_p, unpack_buffer);
printf("\nlength is %d\n", *length_p);
fwrite(unpack_buffer, 1, *length_p, out);
fclose(out);
}
closesocket(sockConn);
}

delete[] buffer;
delete[] send_buffer;
delete[] unpack_buffer;
return 0;
}

/*
** 包头共20个字节,内容如下
** (1)"EEEEEEE"(7个E占8字节)为包的开始标识;
** (2)类型标识占四字节(目前0代表bmp、1代表jpg);
** (3)长度标识占四字节;
** (4)序号标识占四字节;
*/
void
package_head(int type, int length, int seq, char *head)
{

char start_a[8] = "EEEEEEE";

char type_a[8];
sprintf_s(type_a, "%d", type);

char length_a[8];
sprintf_s(length_a, "%d", length);

char seq_a[8];
sprintf_s(seq_a, "%d", seq);

memset(head, 0, 32);
memcpy(head, start_a, 8);
memcpy(head + 8, type_a, 8);
memcpy(head + 16, length_a, 8);
memcpy(head + 24, seq_a, 8);

int a = atoi(length_a);
printf("length_a is %d\n", a);
}

/*
** 包尾8个字节,字符串“FFFFFFF”(7个F)
*/
void
package_tail(char *tail)
{
char end_a[8] = "FFFFFFF";

memcpy(tail, end_a, 8);
}

void pack(int type, int length, int seq, char *pic, char *pack)
{
char head[32];
char tail[8];

package_head(type, length, seq, head);
package_tail(tail);

memcpy(pack, head, 32);
memcpy(pack + 32, pic, length);
memcpy(pack + 32 + length, tail, 8);
}


void
unpack(char *in, int *type, int *length, int *seq, char *out)
{
char type_a[8];
char length_a[8];
char seq_a[8];

memset(type_a, 0, 8);
memset(length_a, 0, 8);
memset(seq_a, 0, 8);

char head[8] = "EEEEEEE";
char head_get[8];

char tail[8] = "FFFFFFF";
char tail_get[8];

memset(head_get, 0, 8);
memcpy(head_get, in, 8);

if (memcmp(head, head_get, 8) != 0)
perror("TCP package head error");

memcpy(type_a, in + 8, 8);
memcpy(length_a, in + 16, 8);
memcpy(seq_a, in + 24, 8);

*type = atoi(type_a);
*length = atoi(length_a);
*seq = atoi(seq_a);

memset(tail_get, 0, 8);
memcpy(tail_get, in + 32 + *length, 8);

if (memcmp(tail, tail_get, 8) != 0)
perror("TCP package tail error");

memcpy(out, in + 32, *length);

}


client:
// Client.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <winsock.h>
#include "queue.h"
#include <assert.h>
#include <string.h>
#pragma comment(lib, "ws2_32.lib")

#define BUFFER_SIZE 1*1024*1024

#define QUEUE_SIZE 9
#define ARRAY_SIZE (QUEUE_SIZE + 1)
#define ELEMENT_SIZE (1024*1024)

void insert_queue(const char*);
void delete_queue(void);
char* first(void);
int is_empty(void);
int is_full(void);

static char queue[ARRAY_SIZE * ELEMENT_SIZE];
static int front = 1;
static int rear = 0;

void unpack(char *in, int *type, int *length, int *seq, char *out);

int main()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;

FILE *out;
char *buffer = new char[BUFFER_SIZE];
char *recv_buffer = new char[32 + BUFFER_SIZE + 8];
int *type_p = new int(0);
int *length_p = new int(0);
int *seq_p = new int(0);

wVersionRequested = MAKEWORD(1, 1);

err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0) {
perror("WSAStartup() Error!");
Sleep(2000);
return 0;
}

if (LOBYTE(wsaData.wVersion) != 1 ||
HIBYTE(wsaData.wVersion) != 1) {
WSACleanup();
perror("WSAStartup() Error!");
Sleep(2000);
return 0;
}

err = fopen_s(&out, "2.jpg", "wb");
if (err != 0) {
perror("fopen_s.., 2.jpg, .. Error");
Sleep(2000);
return 0;
}

SOCKET sockClient = socket(AF_INET, SOCK_STREAM, 0);
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
addrSrv.sin_port = htons(6000);
addrSrv.sin_family = AF_INET;
int i = 0;

connect(sockClient, (sockaddr*)&addrSrv, sizeof(sockaddr));
while (i < 1) {
Sleep(1000);
char recvBuffer[100];
//recv(sockClient, recvBuffer, 100, 0);
recv(sockClient, recv_buffer, 32 + BUFFER_SIZE + 8, 0);
unpack(recv_buffer, type_p, length_p, seq_p, buffer);
fwrite(buffer, 1, *length_p, out);
fclose(out);
//insert_queue(buffer);
printf("%s\n", recvBuffer);

char sendBuffer[100];
sprintf_s(sendBuffer, "%d client send", i);
//send(sockClient, sendBuffer, 100, 0);
send(sockClient, sendBuffer, sizeof(sendBuffer), 0);
i++;
printf("length is %d\n", *length_p);
Sleep(5000);
}
closesocket(sockClient);

delete[] buffer;
delete[] recv_buffer;

return 0;
}


void
insert_queue(const char* buf)
{
assert(!is_full());
rear = (rear + 1) % ARRAY_SIZE;
memcpy(queue + rear*ELEMENT_SIZE, buf, ELEMENT_SIZE);
}

void
delete_queue(void)
{
assert(!is_empty());
memset(queue + front*ELEMENT_SIZE, 0, ELEMENT_SIZE);
front = (front + 1) % ARRAY_SIZE;
}

char *
first(void)
{
assert(!is_empty());
return queue + front*ELEMENT_SIZE;
}

int
is_empty()
{
return (rear + 1) % ARRAY_SIZE == front;
}

int
is_full()
{
return (rear + 2) % ARRAY_SIZE == front;
}

void
unpack(char *in, int *type, int *length, int *seq, char *out)
{
char type_a[8];
char length_a[8];
char seq_a[8];

memset(type_a, 0, 8);
memset(length_a, 0, 8);
memset(seq_a, 0, 8);

char head[8] = "EEEEEEE";
char head_get[8];

char tail[8] = "FFFFFFF";
char tail_get[8];

memset(head_get, 0, 8);
memcpy(head_get, in, 8);

if (memcmp(head, head_get, 8) != 0)
perror("TCP package head error");

memcpy(type_a, in + 8, 8);
memcpy(length_a, in + 16, 8);
memcpy(seq_a, in + 24, 8);

*type = atoi(type_a);
*length = atoi(length_a);
*seq = atoi(seq_a);

memset(tail_get, 0, 8);
memcpy(tail_get, in + 32 + *length, 8);

if(memcmp(tail, tail_get, 8) != 0)
perror("TCP package tail error");

memcpy(out, in + 32, *length);

}


...全文
1094 25 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
yiyefangzhou24 2018-09-03
  • 打赏
  • 举报
回复
2
3
4
5
6
typedef struct
{
unsigned int packet_num;//一次传送分包数量
unsigned int packet_index;//当前传送包的序号
unsigned char data[1024];//每个包的大小
}tcp_packet;
天妒刺客 2018-08-31
  • 打赏
  • 举报
回复
我拿了你的代码学习了一下.顺便学习了VS2017,整了一天,调试发现, 根据图片显示的效果以及文件头正确 文件尾显示不正确,说明只接受到了数据包的前部分,后部分没有收到, 发现是你的发送和接收的缓存设置过大. 1M太大了,建议换成1024b,把数据包拆分发送,不存在丢失现象了,图片解析正确.
大尾巴猫 2017-11-29
  • 打赏
  • 举报
回复
tcp发送和接收不是同步的 不能依赖发送一次就接收一次。 tcp没有保证一次能把你要发送的发送完整,同样接收也是这样。 要根据send或者recv返回的值,判断是否发送或者接收完整。不完整就继续发送或者接收。 发送和接收的过程不是一次,需要在循环中进行,完整了才退出循环。
大尾巴猫 2017-11-29
  • 打赏
  • 举报
回复
引用 21 楼 HANKER131523 的回复:
[quote=引用 18 楼 ananluowei 的回复:] tcp发送和接收不是同步的 不能依赖发送一次就接收一次。 tcp没有保证一次能把你要发送的发送完整,同样接收也是这样。 要根据send或者recv返回的值,判断是否发送或者接收完整。不完整就继续发送或者接收。 发送和接收的过程不是一次,需要在循环中进行,完整了才退出循环。
你说的对,可是send和recv函数里面有一个包的字节数的参数,这个一般要选多大了,我试了好多次,发现几M貌似都可以的,而且单次发单次收都没什么问题[/quote] 一个包的大小是无所谓的,只要发送过去的格式,接收方能解析,能知道这个包多大就可以。发送和接收的过程不是一次send或者recv的,给你看一个简单的发送接收的函数代码
//增加一个send、recv共用的函数,减少重复代码

int sendrecv(SOCKET sock, char* buff, unsigned int len, bool sendflag)
{
	int ret = 0;
	do
	{
		int i;
		if (sendflag) //发送标志,接收为false
			i = send(sock, buff + ret, len - ret, 0);
		else
			i = recv(sock, buff + ret, len - ret, 0);
		if (i == 0)
		{
			//cout << "connect closed\n";
			ret = i;
			break;
		}
		else if (i < 0)
		{
			//cout << "recv failed with error: " << WSAGetLastError() << endl;
			ret = i;
			break;
		}
		else
		{	
			ret += i;
		}
	} while (ret >0 && ret < len);
	return ret;
}


inline int recvtobuff(SOCKET sock, char* buff, unsigned int len)
{
	return sendrecv(sock, buff, len, false);
}

inline int sendfrombuff(SOCKET sock, char* buff, unsigned int len)
{
	return sendrecv(sock, buff, len, true);
}
绿领巾童鞋 2017-11-29
  • 打赏
  • 举报
回复
引用 20 楼 HANKER131523 的回复:
[quote=引用 19 楼 chenandczh 的回复:] 包协议里面 应该添加 一些信息细节 。例如 ,图片总的BYTE大小,总包数,当前包序号,这样就能保证接收后数据整合处理。
兄弟,你看程序了吗,里面有的[/quote] 有跟逻辑正确是两码事,既然有这个思路,为什么不去调一下,完成接收后对比总包数以及计算一下文件MD5和采集收集的全部字节的MD5是否在一致。等你确认收集过程没有问题再看看是不是图片解码问题。
HANKER131523 2017-11-29
  • 打赏
  • 举报
回复
引用 18 楼 ananluowei 的回复:
tcp发送和接收不是同步的 不能依赖发送一次就接收一次。 tcp没有保证一次能把你要发送的发送完整,同样接收也是这样。 要根据send或者recv返回的值,判断是否发送或者接收完整。不完整就继续发送或者接收。 发送和接收的过程不是一次,需要在循环中进行,完整了才退出循环。
你说的对,可是send和recv函数里面有一个包的字节数的参数,这个一般要选多大了,我试了好多次,发现几M貌似都可以的,而且单次发单次收都没什么问题
HANKER131523 2017-11-29
  • 打赏
  • 举报
回复
引用 19 楼 chenandczh 的回复:
包协议里面 应该添加 一些信息细节 。例如 ,图片总的BYTE大小,总包数,当前包序号,这样就能保证接收后数据整合处理。
兄弟,你看程序了吗,里面有的
绿领巾童鞋 2017-11-29
  • 打赏
  • 举报
回复
包协议里面 应该添加 一些信息细节 。例如 ,图片总的BYTE大小,总包数,当前包序号,这样就能保证接收后数据整合处理。
qq_41177303 2017-11-28
  • 打赏
  • 举报
回复
这么复杂的程序,佩服,一个菜鸟的我表示看不懂,写这个程序语言多久?要向你学习
Drunkard2000 2017-11-28
  • 打赏
  • 举报
回复
发送时,检查下send返回值,看下是否全部成功了,建议分多次发送,每次发送一小块。 tcp是流式的,不一定就是服务器发了一个数据包,客户端就收到一个数据包
老马何以识途 2017-11-28
  • 打赏
  • 举报
回复
TCP不仅是可靠不丢包,而且保证了顺序,除非连接被重置,否则根本不需要关心这些问题。
HANKER131523 2017-11-28
  • 打赏
  • 举报
回复
引用 9 楼 hzy_76 的回复:
那就更是跟发送顺序无关了,要知道TCP的基本特点正是“可靠连接”,数据顺序都要自己处理了,干嘛不用UDP? [quote=引用 8 楼 HANKER131523 的回复:] [quote=引用 7 楼 hzy_76 的回复:] TCP协议应该已经保证了数据的顺序,除非你重新创建了socket连接。所以应该不是这方面的问题。 你可以标记一下数据,调试看看发送的每个数据包和对端收到的都是什么。
我现在只是用了一次发送和一次接收来测试[/quote][/quote] TCP不是说可靠不丢包吗,这个也不是我一个人决定的,也本着学东西的态度试试
HANKER131523 2017-11-28
  • 打赏
  • 举报
回复
引用 10 楼 cfjtaishan 的回复:
[quote=引用 5 楼 HANKER131523 的回复:] [quote=引用 2 楼 cfjtaishan 的回复:] 有可能是网络动荡,即服务器是顺序发送的,但是到客户端收到的数据可能不是按照一个个接收,有可能一下子接收到2个包(即服务器发2次,客户端一次接收)这就是为什么如果中间不加包头包尾图片就正常; 解决网络动荡的方法是客户端使用环形缓冲区,也可以理解为缓冲队列;每个收到的包先存到缓冲队列里,然后再从缓冲队列里取数据解析,即使每个从服务到的数据都加了包头和包尾,我们从缓冲队列里取数据然后分别解析,如果收到的包头(包头里有数据长度吧)都包含数据长度,那么根据这个长度和缓存队列里的数据长度比较,若包头里记录的长度大于当前缓存队列里数据长度,那么则不读取,反之则读取解析(去掉包头和包尾)
有可能是网络动荡,即服务器是顺序发送的,但是到客户端收到的数据可能不是按照一个个接收,有可能一下子接收到2个包(即服务器发2次,客户端一次接收)这就是为什么如果中间不加包头包尾图片就正常;,这句话不太理解,感觉没什么关系啊[/quote] 网络动荡是指网络有可能好有可能不好;如果网络好,服务器发送一个,客户端马上收到了,这个我们想要的,但是有时候网络不像我们那样想的顺畅;不然我们下载东西,怎么会有时候快,有时候慢呢。[/quote] 我用的是本机的127.0.0.1,应该不存在动荡的问题吧
自信男孩 2017-11-28
  • 打赏
  • 举报
回复
引用 11 楼 HANKER131523 的回复:
[quote=引用 10 楼 cfjtaishan 的回复:] [quote=引用 5 楼 HANKER131523 的回复:] [quote=引用 2 楼 cfjtaishan 的回复:] 有可能是网络动荡,即服务器是顺序发送的,但是到客户端收到的数据可能不是按照一个个接收,有可能一下子接收到2个包(即服务器发2次,客户端一次接收)这就是为什么如果中间不加包头包尾图片就正常; 解决网络动荡的方法是客户端使用环形缓冲区,也可以理解为缓冲队列;每个收到的包先存到缓冲队列里,然后再从缓冲队列里取数据解析,即使每个从服务到的数据都加了包头和包尾,我们从缓冲队列里取数据然后分别解析,如果收到的包头(包头里有数据长度吧)都包含数据长度,那么根据这个长度和缓存队列里的数据长度比较,若包头里记录的长度大于当前缓存队列里数据长度,那么则不读取,反之则读取解析(去掉包头和包尾)
有可能是网络动荡,即服务器是顺序发送的,但是到客户端收到的数据可能不是按照一个个接收,有可能一下子接收到2个包(即服务器发2次,客户端一次接收)这就是为什么如果中间不加包头包尾图片就正常;,这句话不太理解,感觉没什么关系啊[/quote] 网络动荡是指网络有可能好有可能不好;如果网络好,服务器发送一个,客户端马上收到了,这个我们想要的,但是有时候网络不像我们那样想的顺畅;不然我们下载东西,怎么会有时候快,有时候慢呢。[/quote] 我用的是本机的127.0.0.1,应该不存在动荡的问题吧[/quote] 如果是本地的服务器和客户端,那么不存在网络动荡问题,但是需要考虑CPU调用机制,因为在同一台电脑上,服务器和客户端是属于不同的两个进程,因此他们的通信可以简单的理解为进程间通信(异步的),这样也可能出现类似网络动荡的问题,比如给服务器的时间片多一些,给客户端的时间片少一些。
赵4老师 2017-11-28
  • 打赏
  • 举报
回复
不知道有多少前人掉在TCP Socket send(人多)send(病少)send(财富) recv(人多病)recv(少财富) 陷阱里面啊! http://bbs.csdn.net/topics/380167545
自信男孩 2017-11-27
  • 打赏
  • 举报
回复
引用 5 楼 HANKER131523 的回复:
[quote=引用 2 楼 cfjtaishan 的回复:] 有可能是网络动荡,即服务器是顺序发送的,但是到客户端收到的数据可能不是按照一个个接收,有可能一下子接收到2个包(即服务器发2次,客户端一次接收)这就是为什么如果中间不加包头包尾图片就正常; 解决网络动荡的方法是客户端使用环形缓冲区,也可以理解为缓冲队列;每个收到的包先存到缓冲队列里,然后再从缓冲队列里取数据解析,即使每个从服务到的数据都加了包头和包尾,我们从缓冲队列里取数据然后分别解析,如果收到的包头(包头里有数据长度吧)都包含数据长度,那么根据这个长度和缓存队列里的数据长度比较,若包头里记录的长度大于当前缓存队列里数据长度,那么则不读取,反之则读取解析(去掉包头和包尾)
有可能是网络动荡,即服务器是顺序发送的,但是到客户端收到的数据可能不是按照一个个接收,有可能一下子接收到2个包(即服务器发2次,客户端一次接收)这就是为什么如果中间不加包头包尾图片就正常;,这句话不太理解,感觉没什么关系啊[/quote] 网络动荡是指网络有可能好有可能不好;如果网络好,服务器发送一个,客户端马上收到了,这个我们想要的,但是有时候网络不像我们那样想的顺畅;不然我们下载东西,怎么会有时候快,有时候慢呢。
老马何以识途 2017-11-27
  • 打赏
  • 举报
回复
那就更是跟发送顺序无关了,要知道TCP的基本特点正是“可靠连接”,数据顺序都要自己处理了,干嘛不用UDP?
引用 8 楼 HANKER131523 的回复:
[quote=引用 7 楼 hzy_76 的回复:] TCP协议应该已经保证了数据的顺序,除非你重新创建了socket连接。所以应该不是这方面的问题。 你可以标记一下数据,调试看看发送的每个数据包和对端收到的都是什么。
我现在只是用了一次发送和一次接收来测试[/quote]
HANKER131523 2017-11-27
  • 打赏
  • 举报
回复
引用 7 楼 hzy_76 的回复:
TCP协议应该已经保证了数据的顺序,除非你重新创建了socket连接。所以应该不是这方面的问题。 你可以标记一下数据,调试看看发送的每个数据包和对端收到的都是什么。
我现在只是用了一次发送和一次接收来测试
老马何以识途 2017-11-27
  • 打赏
  • 举报
回复
TCP协议应该已经保证了数据的顺序,除非你重新创建了socket连接。所以应该不是这方面的问题。 你可以标记一下数据,调试看看发送的每个数据包和对端收到的都是什么。
HANKER131523 2017-11-27
  • 打赏
  • 举报
回复
引用 4 楼 cfjtaishan 的回复:
[quote=引用 3 楼 HANKER131523 的回复:] [quote=引用 2 楼 cfjtaishan 的回复:] 有可能是网络动荡,即服务器是顺序发送的,但是到客户端收到的数据可能不是按照一个个接收,有可能一下子接收到2个包(即服务器发2次,客户端一次接收)这就是为什么如果中间不加包头包尾图片就正常; 解决网络动荡的方法是客户端使用环形缓冲区,也可以理解为缓冲队列;每个收到的包先存到缓冲队列里,然后再从缓冲队列里取数据解析,即使每个从服务到的数据都加了包头和包尾,我们从缓冲队列里取数据然后分别解析,如果收到的包头(包头里有数据长度吧)都包含数据长度,那么根据这个长度和缓存队列里的数据长度比较,若包头里记录的长度大于当前缓存队列里数据长度,那么则不读取,反之则读取解析(去掉包头和包尾)
你意思是我每次接收的数据都设置为很小,然后多次接收,那这个大小一般应该设置为多大呢[/quote] 我说的环形缓冲区,建议从网上找一个这个技术点;这个需要多线程操作了,即在客户端用一个线程去接收写到环形缓冲区里,一个线程去读环形缓冲区,然后解析数据报文;[/quote] 我这个程序里含有用数组实现的缓冲区程序的,只是,我前面发现1M左右的图片直接发过来好像就能接受成功,就不用了
加载更多回复(5)

70,021

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧