首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VC/MFC >

tcp接收资料,文本什么的,对着呢,图片接收就花了

2013-02-03 
tcp接收文件,文本什么的,对着呢,图片接收就花了tcp接收文件,文本什么的,对着呢,图片接收就花了服务器#incl

tcp接收文件,文本什么的,对着呢,图片接收就花了
tcp接收文件,文本什么的,对着呢,图片接收就花了

服务器

#include<windows.h>
#include<stdio.h>
#include<stdlib.h>
#include "string.h"

#pragma comment(lib,"ws2_32.lib")

#define PORT 6666
#define IPADDR "127.0.0.1"
#define BACKLOG 20
#define FILENAME 200        //文件名长度
#define BUFFERSIZE 1024

#define LENGTH 200

struct FILEHEAD  //文件信息结构
{
char path_buffer[LENGTH];//文件绝对路径加完整名
char filename[LENGTH];//文件名
char ext[LENGTH];//文件扩展名
unsigned int length;//文件长度

};

FILEHEAD file; 

//得到文件头信息,使用全局变量函数没有参数
void getFileInformation()
{
printf( "file information :n" );
//printf( "  Drive: %sn", drive );
//printf( "  Dir: %sn", dir );
printf( "  Filename: %sn", file.filename );
printf( "  Ext: %sn", file.ext );
printf( "  length is btye: %ld btyen", file.length );
}

int main(void)
{

WSADATA wsadata;//这个结构被用来存储 被WSAStartup函数调用后返回的windows数据
WSAStartup(MAKEWORD(2,0),&wsadata);//WSAStarup,是Windows SocKNDs Asynchronous的启动命令申请2.0版本的套接字
SOCKET sock_trans=socket(AF_INET,SOCK_STREAM,0);

if (INVALID_SOCKET==sock_trans ||SOCKET_ERROR==sock_trans)
{
perror("socket");
printf("socket error!!!n");
exit(1);
}

SOCKADDR_IN saddr;
saddr.sin_family=AF_INET;
saddr.sin_port=htons(PORT);
saddr.sin_addr.S_un.S_addr=inet_addr(IPADDR);

int sadlen=sizeof(saddr);



if (bind(sock_trans,(SOCKADDR*)(&saddr),sadlen)==SOCKET_ERROR)
{

perror("bind error");
exit(2);

}
else printf ("bind port ok!n");

//int vlisten=50;

if (listen(sock_trans,20)==SOCKET_ERROR)
{
perror("listen");
exit(3);
}
else
printf ("now listenning.....n");

int saddrlen=sizeof(saddr);

SOCKET newsock=accept(sock_trans,(SOCKADDR*)&saddr,&saddrlen);

char buf[BUFFERSIZE]={0};//接收缓冲区
//char filename[FILENAME]={0};
ZeroMemory(buf,1024);//memset功能一样

//接收文件头信息
printf("接收文件头信息...n");
int length_file_info=recv(newsock,(char *)&file,BUFFERSIZE,0);//接收长度为文件头信息的长度
if (length_file_info<=0)
{
exit(0);
}

getFileInformation();


//printf("input the save file name:n");
//scanf("%s",&file.filename);
//接收来的文件,分离出后缀名,保存为receive+file.ext,客户端发送过来的文件头中对后缀名的分割加了点"."
char *s="receive";
ZeroMemory(file.filename,LENGTH);
strcpy(file.filename,s);
strcat(file.filename,file.ext);

FILE * fp=NULL;
fp=fopen(file.filename,"w+");//此处以后应当先接受文件名。之后打开文件,接受客户端的数据写文件。
if(fp==NULL)
{
perror("open file:");
exit(0);
}

printf("要接收的文件名为:");
printf(file.filename);//打印文件名

printf ("n catch file now....n");


int relen=0;//recv接收到的字节
/*
********************************************************************************
1.n>0,正常读取n个字节
2.n==0,socket对方节点正常shutdown  
3.n==-1,未能正常读取数据,根据值不同errno被置为几种情况
********************************************************************************


*/

Sleep(3000);

printf("开始接收...n");
//循环接收client发来的数据////////////////////////////////////////////////////////
while(1)
{
relen=recv(newsock,buf,1024,0);
fwrite(buf,1,relen,fp);
//printf("接受了一次!n");
fflush(fp);

if (relen==0)
{
break;
}
printf(".");
}
printf("n接收完成...n");

fclose(fp);
fp=NULL;
closesocket(newsock);
closesocket(sock_trans);
WSACleanup();

system("pause");

return 0;

}





客户端:
#include <stdio.h>
#include <windows.h>
#include <stdlib.h>

#define FILENAME 200
#define BUFFER 1024


#pragma comment(lib, "ws2_32.lib")  

#define LENGTH 200


struct FILEHEAD  //文件信息结构
{
char path_buffer[LENGTH];//文件绝对路径
char filename[LENGTH];//文件名
char ext[LENGTH];//文件扩展名
unsigned int length;//文件长度

};

FILEHEAD file; 

void setFileInformation()
{
memset(&file,0,sizeof(FILEHEAD)); 

//_makepath( path_buffer, "c", "\sample\crt", "makepath", "c" );
printf( "input the path and name : n");
scanf("%s",file.path_buffer);
_splitpath( file.path_buffer, NULL, NULL, file.filename, file.ext );

FILE *fp= NULL;
fp=fopen(file.path_buffer,"r");
if (NULL==fp)
{
printf("cannot open the %s n",file.path_buffer);
exit(0);
}

fseek(fp,0l,SEEK_END);
file.length=ftell(fp);

//fclose(fp);
//fp = NULL; //需要指向空,否则会指向原打开文件地址

printf( "file head information:n" );
//printf( "  Drive: %sn", drive );
//printf( "  Dir: %sn", dir );
printf( "  Filename: %sn", file.filename );
printf( "  Ext: %sn", file.ext );
printf( "  length is btye: %ld btyen", file.length );
}



int main(int argc, char *argv[])
{
WSADATA wsadata;
WSAStartup(MAKEWORD(2,0),&wsadata);
SOCKET sock_trans=socket(AF_INET,SOCK_STREAM,0);

if (sock_trans==0)
{
printf ("socket build faile!!n");
exit(1);
}

printf ("target pc's IP address: 127.0.0.1n");

//如果正式调试,将服务器端ip写死。

SOCKADDR_IN sockadd;
sockadd.sin_family=AF_INET;
sockadd.sin_port=htons(6666);
sockadd.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");

int con_info=connect(sock_trans,(SOCKADDR*)&sockadd,sizeof(sockadd));

if (con_info==SOCKET_ERROR)
{
printf ("connect fail!n");
//exit(2);
}

Sleep(1000);

setFileInformation();

FILE *fp;
fp=fopen(file.path_buffer,"rb");
if (fp==NULL)
{
perror("nopen file error:");
exit(1);
}

//freed_return_val=fread(buf,1,1024,fp);//读文件字符
char buf[BUFFER];
int fread_return_val=0;//文件读出字符的返回值

//发送文件头信息
printf("发送文件头信息...n");
send(sock_trans,(char *)&file,sizeof(file),0);

printf("发送文件信息...n");
while (1)
{
fread_return_val=fread(buf,1,1024,fp);
if (0==fread_return_val)


{
break;
}
//freed_return_val=fread(buf,1,1024,fp);
send(sock_trans,buf,fread_return_val,0);
printf(".");
}

fclose(fp);

closesocket(sock_trans);
WSACleanup();
printf("n发送完成...n");

return 0;

}


[解决办法]
有数据被损坏了。在每包数据加上校验。
[解决办法]
在发送结构后面加四个字节做checksum,内容就是buffer所有字节的和,最简单的校验,简单有效。:)
[解决办法]
试试用二进制方式写入文件
fp=fopen(file.filename,"wb+");
[解决办法]
服务端:
int length_file_info=recv(newsock,(char *)&file,BUFFERSIZE,0);

如果收到的数据小于sizeof(FILEHEAD)或者大于sizeof(FILEHEAD),会怎样?
网络编程不同与函数调用,我不止一次说过这个问题了。
[解决办法]
http://blog.csdn.net/zhoujielunzhimi/article/details/8190601
我也写了一个,传图片没问题。你对照着看看吧
[解决办法]
提醒一下,你的发送端程序不严谨。

while()
{
    Send();
}

closeSocket();


发送端问题:
1、首先send必须判断返回值,这里存在数据丢失风险。
2、send完毕直接closesocket,也存在数据丢失风险。

热点排行