如何用win socket实现客户端和服务器端的文件传送??
客户端用两个函数getfile(),sendfile()来实现向服务器取文件和送文件的过程。取来的文件保存在本地。请大家帮帮忙,最好有server端和client端的源程序。谢谢了。 问题点数:100、回复次数:7Top
1 楼zhouzcy()回复于 2002-11-18 15:35:20 得分 50
下面给出服务器端代码:void SendFile()
{
#define PORT 34000 /// Select any free port you wish
AfxSocketInit(NULL);
CSocket sockSrvr;
sockSrvr.Create(PORT); // Creates our server socket
sockSrvr.Listen(); // Start listening for the client at PORT
CSocket sockRecv;
sockSrvr.Accept(sockRecv); // Use another CSocket to accept the connection
CFile myFile;
myFile.Open("C:\\ANYFILE.EXE", CFile::modeRead | CFile::typeBinary);
int myFileLength = myFile.GetLength(); // Going to send the correct File Size
sockRecv.Send(&myFileLength, 4); // 4 bytes long
byte* data = new byte[myFileLength];
myFile.Read(data, myFileLength);
sockRecv.Send(data, myFileLength); //Send the whole thing now
myFile.Close();
delete data;
sockRecv.Close();
}
以下是客户端代码 void GetFile()
{
#define PORT 34000 /// Select any free port you wish
AfxSocketInit(NULL);
CSocket sockClient;
sockClient.Create();
// "127.0.0.1" is the IP to your server, same port
sockClient.Connect("127.0.0.1", PORT);
int dataLength;
sockClient.Receive(&dataLength, 4); //Now we get the File Size first
byte* data = new byte[dataLength];
sockClient.Receive(data, dataLength); //Get the whole thing
CFile destFile("C:\\temp\\ANYFILE.EXE",
CFile::modeCreate | CFile::modeWrite | CFile::typeBinary);
destFile.Write(data, dataLength); // Write it
destFile.Close();
delete data;
sockClient.Close();
}
详细资料请参阅http://bbs.glorisoft.com/ubb/Forum2/HTML/000206.htmlTop
2 楼lytt(流雨亭)回复于 2002-11-18 17:08:20 得分 0
谢谢zhouzcy,不知道能否提供linux下c的实现代码。Top
3 楼dhy311(好好学习,天天向上)回复于 2002-11-18 17:48:33 得分 50
还是建议你用ftp来传送把,比较简单的,当然你要确定服务器端的ftp服务是开着的,
实现很简单,只要你想远程的ftp服务器(21端口)输入 user 和pass等等一些命令,里面都有现成的命令的
比较简单
而且安全,高效,说白了,就是编写一个ftp客户端类似的东西Top
4 楼dhy311(好好学习,天天向上)回复于 2002-11-18 17:50:29 得分 0
/***************************************************************/
/*功能描述:使用FTP取得文件 */
/*输入参数:ip,port:目标机器的IP地址和FTP端口(21);
user,passwd:登陆目标机器的用户名和口令;
sourcefile:需要下载的文件名(包括路径) */
/*返回值:(0--成功,destfile--下载在本地的文件名),-1--失败 */
/***************************************************************/
int GetFTPData(char *ip,int port,char *user,char *passwd,char *sourcefile,char *destfile,long fsize)
{
char msg[FTP_SIZE];
int fd;
int ftpId,dataId,dataPort;
int i;
long readCount;
struct stat strTemp;
char errmsg[255];
memset(&strTemp,0,sizeof(struct stat));
if(InitConnectSocket(ip,port,&ftpId)<0){
printf("\nGetFTPData:初始化连接FTP端口错误!");
return -1;
}
/* get ftp info */
memset(msg,0,FTP_SIZE);
recv(ftpId,msg,FTP_SIZE,0);
msg[FTP_SIZE-1]=0;
printf("\n1*%s",msg);
if(strncmp(msg,"220-",4)==0){
recv(ftpId,msg,FTP_SIZE,0);
msg[FTP_SIZE-1]=0;
printf("\n%s",msg);
}
/* send user */
memset(msg,0,FTP_SIZE);
sprintf(msg,"user %s\n",user);
if(ProcessFTPCommand(ftpId,msg,1,0)<0) return -1;
/* send password */
memset(msg,0,FTP_SIZE);
sprintf(msg,"pass %s\n",passwd);
if(ProcessFTPCommand(ftpId,msg,2,0)<0) return -1;
/* binary */
memset(msg,0,FTP_SIZE);
sprintf(msg,"type i\n");
if(ProcessFTPCommand(ftpId,msg,3,0)<0) return -1;
/* get data port */
memset(msg,0,FTP_SIZE);
sprintf(msg,"pasv\n");
if(ProcessFTPCommand(ftpId,msg,6,&dataPort)<0) return -1;
/* connect data server */
if(InitConnectSocket(ip,dataPort,&dataId)<0){
printf("\nInitFTPConnect:连接数据服务器错误(端口%d)",dataPort);
return -1;
}
/* prepare for get data */
memset(msg,0,FTP_SIZE);
sprintf(msg,"retr %s\n",sourcefile);
if(ProcessFTPCommand(ftpId,msg,5,0)<0) return -1;
/* open local file */
unlink(destfile);
if((fd=open(destfile,O_WRONLY|O_CREAT,0666))<0){
printf("\nOpen file %s error !");
return -1;
}
/* get data */
readCount=0;
for(;;)
{
i=0;
i=read(dataId,msg,FTP_SIZE);
if(i <= 0) break;
if(write(fd,msg,i) < 0)
{
printf("ERROR: download file cannot write to local\n");
return -1;
}
readCount+=i;
}
/*printf("\nreadCount=%u",readCount);*/
close(fd);
close(dataId);
close(ftpId);
/*判断FTP的结果是否正确(文件是否相同大小)*/
if(stat(destfile,&strTemp)==-1||( off_t)(strTemp.st_size)!=fsize){
sprintf(errmsg,"下载错误:统计文件%s的大小%ld与远程文件大小%ld不符!",destfile,strTemp.st_size,fsize);
writeErrLog(errmsg);
return -1;
}
else
{
return 0;
}
/*
if(readCount==strTemp.st_size||readCount<=0)
return 0;
else{
printf("\nFTP下载的文件的大小不一致!");
return -1;
}
*/
}
Top
5 楼dhy311(好好学习,天天向上)回复于 2002-11-18 17:53:03 得分 0
int ProcessFTPCommand(int ftpId,char *sCommand,int type,int *port){
int n;
char msg[FTP_SIZE];
n=send(ftpId,sCommand,strlen(sCommand),0);
memset(msg,0,FTP_SIZE);
n=recv(ftpId,msg,FTP_SIZE,0);
msg[FTP_SIZE-1]=0;
/*
if(FtpIsVerify(type,msg)<0){
printf("\nFTP命令错误:%s",msg);
return -1;
}
*/
printf("%s",msg);
if(type==6){
/* get port */
for( ; n>0; n--)
if(msg[n]==',') break;
if(n==0)
{
printf("ERROR: get dataport error(%s)\n",msg);
return -1;
}
*port=atoi(msg+n+1);
for( n--; n>0; n-- )
if(msg[n]==',') break;
if(n==0)
{
printf("ERROR: get dataport error\n");
return -1;
}
(*port)+=atoi(msg+n+1)*256;
printf("data port=%d\n",*port);
}
return 0;
}Top
6 楼lytt(流雨亭)回复于 2002-11-19 12:02:45 得分 0
谢谢dhy,不过我要做的是一个网络设备的远程配置程序,当client与server建立连接时,server应该传送一个配置文件到本地,然后关闭。client打开文件修改保存后,再建立连接传送文件给server端。Top
7 楼lnm(网狐)回复于 2002-11-19 14:10:12 得分 0
请问zhouzcy:
你的程序是直接把文件一次性send过去的,要是我的文件比较大呢?比如说我的是部电影,还能这么用么?
在使用socket编程时,常有个“阻塞”+“多线程” VS “非阻塞”的解决方法,你能给个使用多线程阻塞式来传文件的代码吗?
多谢了先。Top




