我把server里面的线程里的printf去掉发现能多接受一点了 server也没有崩溃,但是包没接受完#include<stdio.h> #include <stdlib.h> #include <winsock2.h> #include <string.h>#pragma comment(lib,"ws2_32.lib")#define PORT 9999 #define IPADDR "127.0.0.1" #define BACKLOG 20 #define FILENAME 200 #define LENGTH 200 #define BUFFERSIZE 1024*8struct FILEHEAD //FILE-head struct { char filename[LENGTH];//file name unsigned int length;//the byte of the file};struct FILEDATA //FILE-data struct { char filename[LENGTH];//file name char package[BUFFERSIZE];//package data unsigned int length;//the byte of the file unsigned int index;//index of the package};struct sockaddr_in clientaddr; //Definition of the external variable for thread function callvoid getFileInformation(FILEHEAD file) { printf( "file information :\n" ); printf( " Filename: %s\n", file.filename ); //printf( " Ext: %s\n", file.ext ); printf( " the file length is: %ld btye\n", file.length ); }void showClientinfo() { //获取当前系统时间 SYSTEMTIME st; GetLocalTime(&st); char SysDate[30]; //将systime中的时间转变为字符串存入SysDate[30]; sprintf(SysDate, "%4d-%2d-%2d %2d:%2d:%2d", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond); //Server显示客户端信息 printf("%s Recv from Client [%s:%d] : %s\n", SysDate, inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port)); //服务器向客户端回显信息 }DWORD WINAPI requestThread(LPVOID lparam) { FILEHEAD filehead; FILEDATA filedata; SOCKET newsock=(SOCKET)(LPVOID)lparam; //char buf[BUFFERSIZE]={0}; memset(&filehead,0,sizeof(filehead)); memset(&filedata,0,sizeof(filedata)); showClientinfo(); //printf("等待文件头信息 ...\n"); int length_file_info=recv(newsock,(char *)&filehead,sizeof(filehead),0); if (SOCKET_ERROR==length_file_info) { printf("receive failed!\n"); closesocket(newsock); return -1;
} if (length_file_info<=0) { exit(1);//异常退出 } getFileInformation(filehead);//打印文件信息 FILE *fp=NULL; fp=fopen(filehead.filename,"wb+"); if (NULL==fp) { perror("fail to build the file!!!\n"); exit(1); }
struct FILEHEAD //FILE-head struct { char filename[LENGTH];//file name unsigned int length;//the byte of the file
};
struct FILEDATA //FILE-data struct { char filename[LENGTH];//file name char package[BUFFERSIZE];//package data unsigned int length;//the byte of the file unsigned int index;//index of the package}; 你一个包这么大 发送端明显也要改
你试图接受1024的内容 而你file大小才多大 访问越界了 当然崩溃
不是这样子的,1024是接收的空间,真正传输的是length_file的值
感觉有几个问题,你不停的用同一个buf去接收信息,当中那段是不会错的,到文件末尾,字符不到1024的时候这个buf就会出错了,你到网上学习下怎么样才能正确完整的接收不定大小文件的代码
两个同时发700m的文件,是同一个文件吗,还是不同的文件?
//" "引用的是你程序目录的相对路径中的头文件
#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
#include <string.h>
//添加默认链接库
#pragma comment(lib,"ws2_32.lib")#define PORT 9999
#define IPADDR "127.0.0.1"
#define BACKLOG 20
#define FILENAME 200
#define LENGTH 200
#define BUFFERSIZE 1024struct FILEHEAD //文件信息结构
{
char path_buffer[LENGTH];//文件绝对路径加完整名
char filename[LENGTH];//文件名
char ext[LENGTH];//文件扩展名
unsigned int length;//文件长度
};//FILEHEAD file; //全局文件信息头
struct sockaddr_in clientaddr; //定义外部变量供线程函数调用//得到文件头信息,使用全局变量函数没有参数
void getFileInformation(FILEHEAD file)
{
printf( "file information :\n" );
//printf( " Drive: %s\n", drive );
//printf( " Dir: %s\n", dir );
printf( " Filename: %s\n", file.filename );
printf( " Ext: %s\n", file.ext );
printf( " length is btye: %ld btye\n", file.length );
}void showClientinfo()
{
//获取当前系统时间
SYSTEMTIME st;
GetLocalTime(&st);
char SysDate[30]; //将systime中的时间转变为字符串存入SysDate[30];
sprintf(SysDate, "%4d-%2d-%2d %2d:%2d:%2d", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
//Server显示客户端信息
printf("%s Recv from Client [%s:%d] : %s\n", SysDate, inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port));
//服务器向客户端回显信息
}DWORD WINAPI RequestThread(LPVOID lparam)//线程函数,并发接收请求
{
FILEHEAD file;
SOCKET newsock = (SOCKET)(LPVOID)lparam;
char buf[BUFFERSIZE]={0};//接收缓冲区
memset(buf,0,BUFFERSIZE);//缓冲区清零 showClientinfo();//显示连接信息 printf("等待接收文件头信息...\n");
int length_file_info=recv(newsock,(char *)&file,sizeof(file),0);
if (length_file_info == SOCKET_ERROR)
{
printf("recv failed !\n");
closesocket(newsock);
//WSACleanup();
return -1;
} if (length_file_info<=0)
{
exit(0);//没有成功接收文件头信息
} getFileInformation(file);//打印文件信息
//拼接文件名为receive.文件后缀
//char *s="receive";
//memset(file.filename,0,LENGTH);
//strcpy(file.filename,s);
strcat(file.filename,file.ext);//给文件加上后缀名 FILE *fp=NULL;
fp=fopen(file.filename,"wb+");
if (NULL==fp)
{
perror("fail to build the file!!!\n");
exit(0);
} printf("要接收的文件名为:");
printf(file.filename);//打印文件名
printf ("\n catch file now....\n");
int relength=0;//接收到字节的长度 Sleep(500);
printf("开始接收...\n"); while (1)
{
relength=recv(newsock,buf,BUFFERSIZE,0);
if (relength == SOCKET_ERROR) {
printf("recv failed !\n");
closesocket(newsock);
//WSACleanup();
return -1;
} fwrite(buf,1,relength,fp);
if (0==relength)
{
break;
}
printf(".");
}
printf("\n接收完成...\n"); fflush(fp);
fclose(fp);
fp=NULL; return 0;}
int main(int argc,char *argv[])
{
//初始化winsock版本信息,加载动态链接库(dll)
WSADATA wsData;
if (WSAStartup(MAKEWORD(2,2),&wsData)!=0)
{
printf("WSAStartup failed !!!\n");
return -1;
} //创建监听套接字
SOCKET socklisten;
if((socklisten=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==INVALID_SOCKET)
{
printf("socket failed!!!\n");
WSACleanup();
return -1;
} //设置服务器地址
struct sockaddr_in servaddr; memset(&servaddr,0,sizeof(servaddr));
servaddr.sin_family=AF_INET;
servaddr.sin_port=htons(9999);
servaddr.sin_addr.S_un.S_addr=inet_addr(IPADDR); //绑定socket地址结构到监听套接字
if (bind(socklisten,(sockaddr *)&servaddr,sizeof(servaddr))!=0)
{
printf("binding failed!!!\n");
closesocket(socklisten);
WSACleanup();
} //在server上运行监听
if (listen(socklisten,20)!=0)
{
printf("listen failed !!!\n");
closesocket(socklisten);
WSACleanup();
return -1;
} //接收客户端的连接请求
printf("TCP server is start!!!\n"); //clientaddrlength要有初值,
int client_addr_length = sizeof(clientaddr);
memset(&clientaddr,0,client_addr_length);
SOCKET connect; //循环等待
while (1)
{
if ((connect=accept(socklisten,(sockaddr *)&clientaddr,&client_addr_length))==INVALID_SOCKET)
{
printf("accept failed!!\n");
closesocket(connect);
WSACleanup();
return -1;
} //创建新线程
DWORD ThreadID;
CreateThread(NULL,0,RequestThread,(LPVOID)connect,0,&ThreadID);
}}
printf(file.filename);//打印文件名
server也没有崩溃,但是包没接受完#include<stdio.h>
#include <stdlib.h>
#include <winsock2.h>
#include <string.h>#pragma comment(lib,"ws2_32.lib")#define PORT 9999
#define IPADDR "127.0.0.1"
#define BACKLOG 20
#define FILENAME 200
#define LENGTH 200
#define BUFFERSIZE 1024*8struct FILEHEAD //FILE-head struct
{
char filename[LENGTH];//file name
unsigned int length;//the byte of the file};struct FILEDATA //FILE-data struct
{
char filename[LENGTH];//file name
char package[BUFFERSIZE];//package data
unsigned int length;//the byte of the file
unsigned int index;//index of the package};struct sockaddr_in clientaddr; //Definition of the external variable for thread function callvoid getFileInformation(FILEHEAD file)
{
printf( "file information :\n" );
printf( " Filename: %s\n", file.filename );
//printf( " Ext: %s\n", file.ext );
printf( " the file length is: %ld btye\n", file.length );
}void showClientinfo()
{
//获取当前系统时间
SYSTEMTIME st;
GetLocalTime(&st);
char SysDate[30];
//将systime中的时间转变为字符串存入SysDate[30];
sprintf(SysDate, "%4d-%2d-%2d %2d:%2d:%2d", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
//Server显示客户端信息
printf("%s Recv from Client [%s:%d] : %s\n", SysDate, inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port));
//服务器向客户端回显信息
}DWORD WINAPI requestThread(LPVOID lparam)
{
FILEHEAD filehead;
FILEDATA filedata;
SOCKET newsock=(SOCKET)(LPVOID)lparam;
//char buf[BUFFERSIZE]={0};
memset(&filehead,0,sizeof(filehead));
memset(&filedata,0,sizeof(filedata)); showClientinfo(); //printf("等待文件头信息 ...\n"); int length_file_info=recv(newsock,(char *)&filehead,sizeof(filehead),0);
if (SOCKET_ERROR==length_file_info)
{
printf("receive failed!\n");
closesocket(newsock);
return -1;
}
if (length_file_info<=0)
{
exit(1);//异常退出
} getFileInformation(filehead);//打印文件信息 FILE *fp=NULL;
fp=fopen(filehead.filename,"wb+");
if (NULL==fp)
{
perror("fail to build the file!!!\n");
exit(1);
}
//printf("要接收的文件名为:");
//printf(filehead.filename);//打印文件名
//printf ("\n catch file now....\n");
int recv_length=0;//接收到字节的长度
//Sleep(100);
printf("开始接收...\n");
filedata.index=0;
while (1)
{
recv_length=recv(newsock,(char *)&filedata,sizeof(filedata),0);
if (recv_length == SOCKET_ERROR)
{
printf("recv failed !\n");
closesocket(newsock);
//WSACleanup();
return -1;
}
fwrite(filedata.package,1,BUFFERSIZE,fp);
if (0==recv_length)
{
break;
}
//printf("第%d块接收成功!\n",filedata.index);
}
printf("\n接收完成...\n\n");
fflush(fp);
fclose(fp);
fp=NULL;
return 0;
}int main(int argc,char *argv[])
{
//初始化winsock版本信息,加载动态链接库(dll)
WSADATA wsData;
if (WSAStartup(MAKEWORD(2,2),&wsData)!=0)
{
printf("WSAStartup failed !!!\n");
return -1;
}
//创建套接字
SOCKET socklisten;
if((socklisten=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==INVALID_SOCKET)
{
printf("socket failed!!!\n");
WSACleanup();
return -1;
}
//设置服务器地址
struct sockaddr_in servaddr;
memset(&servaddr,0,sizeof(servaddr));
servaddr.sin_family=AF_INET;
servaddr.sin_port=htons(PORT);
servaddr.sin_addr.S_un.S_addr=inet_addr(IPADDR);
//绑定socket地址结构到监听套接字
if (bind(socklisten,(sockaddr *)&servaddr,sizeof(servaddr))!=0)
{
printf("binding failed!!!\n");
closesocket(socklisten);
WSACleanup();
}
//在server上运行监听
if (listen(socklisten,20)!=0)
{
printf("listen failed !!!\n");
closesocket(socklisten);
WSACleanup();
return -1;
}
//接收客户端的连接请求
printf("TCP server is start!!!\n");
//clientaddrlength要有初值,
int client_addr_length = sizeof(clientaddr);
memset(&clientaddr,0,client_addr_length);
SOCKET connect;
//循环等待
while (1)
{
if ((connect=accept(socklisten,(sockaddr *)&clientaddr,&client_addr_length))==INVALID_SOCKET)
{
printf("accept failed!!!\n");
closesocket(connect);
WSACleanup();
return -1;
}
//创建新线程
DWORD ThreadID;
CreateThread(NULL,0,requestThread,(LPVOID)connect,0,&ThreadID);
}
}
{
recv(s, buff, 4);//这个四个字节应该也要用循环接收的 你自己写吧。 int len = *(int*)buf
int offset = 0;
while(len >0)
{
int iRet = recv(s, buf + offset, len);
if(iRet <= 0)
{
return -1;
}
offset += iRet;
len -= iRet;
}
return offset;
}
{
recv(s, buff, 4);//这个四个字节应该也要用循环接收的 你自己写吧。
int len = *(int*)buf;
int offset = 0;
while(len >0)
{
int iRet = recv(s, buf + offset, len);
if(iRet <= 0)
{
return -1;
}
offset += iRet;
len -= iRet;
}
return offset;
}上面有错 改了一下
send(sock_trans,(char *)&filedata,sizeof(filedata),0);
#define LENGTH 200
#define BUFFERSIZE 1024*8
struct FILEHEAD //FILE-head struct
{
char filename[LENGTH];//file name
unsigned int length;//the byte of the file
};
struct FILEDATA //FILE-data struct
{
char filename[LENGTH];//file name
char package[BUFFERSIZE];//package data
unsigned int length;//the byte of the file
unsigned int index;//index of the package};
你一个包这么大 发送端明显也要改
send(人多)send(病少)send(财富)
recv(人多病)recv(少财富)
陷阱里面啊!
http://topic.csdn.net/u/20120210/09/51109ed0-07b9-41f2-b487-a51597f2ca01.html