TCP传输图片的问题

HANKER131523 HANKER131523 墨衍会员 · AI 创作全网分发 墨衍智能分发 通过墨衍一键同步至各平台 可同步平台 CSDN微信公众号微博知乎掘金百家号博客园抖音小红书 你的文章也可以这样分发 墨衍会员 ¥399起/年,写一次发全网 我也要 + 加入社区
想要在两台电脑间用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);

}


...全文
评论 25
收藏 已收藏
分享
返回顶部
HANKER131523
C语言 70,039 成员 243,237 内容