利用流式套接字实现文件的传输Word格式.docx
- 文档编号:17375327
- 上传时间:2022-12-01
- 格式:DOCX
- 页数:14
- 大小:18.70KB
利用流式套接字实现文件的传输Word格式.docx
《利用流式套接字实现文件的传输Word格式.docx》由会员分享,可在线阅读,更多相关《利用流式套接字实现文件的传输Word格式.docx(14页珍藏版)》请在冰豆网上搜索。
{
intiResult;
charsendline[MAXLINE],recvline[MAXLINE];
charfile[20];
charflong[4];
inti=0;
//文件名发送控制
//初始化缓冲区
FILE*f;
//写文件指针
char*buff;
//读入文件内容
uint32_tnFileLen;
//文件长度
printf("
请输入文件名:
\n"
);
scanf("
%s"
&
file);
f=fopen(file,"
rb"
if(f==NULL)
打开文件失败或文件不存在!
fseek(f,0,SEEK_END);
nFileLen=ftell(f);
rewind(f);
//回到到文件头部
buff=(char*)malloc(nFileLen);
iResult=fread(buff,1,nFileLen,f);
if(iResult!
=nFileLen)
{
printf("
读入文件错误!
return0;
}
memset(sendline,0,MAXLINE);
memset(recvline,0,MAXLINE);
while(i!
recvline[i]=*buff;
i++;
buff++;
//文件名传输结束
sprintf(sendline,"
%s#%d%s"
file,nFileLen,recvline);
iResult=send(s,sendline,sizeof(sendline),0);
if(iResult==SOCKET_ERROR)
{
printf("
send函数调用错误,错误号:
%d"
WSAGetLastError());
return-1;
}
fclose(fp);
文件发送完成!
returniResult;
}
服务器:
inttcp_server_fun_echo(SOCKETs)
FILE*fp;
intiResult=0;
uint32_tnFileLen=1;
charrecvline[MAXLINE];
charfile[10];
memset(file,0,sizeof(file));
memset(recvline,0,sizeof(recvline));
for(;
;
)
iResult=recv(s,&
file[i],1,0);
recv函数调用错误,错误号:
if(file[i]=='
#'
)
break;
else
file[i]='
\0'
fp=fopen(file,"
w+"
if(fp==NULL)
文件打开失败!
"
//接收文件长度
iResult=recv(s,flong,4,0);
sscanf(flong,"
nFileLen);
iResult=recv(s,recvline,nFileLen,0);
}
fputs(recvline,fp);
文件接收成功!
头文件(上次的实验报告中已经写过):
#ifndefp_h//预处理指令,防止重复包含头文件
#include<
stdio.h>
time.h>
ws2tcpip.h>
winsock2.h>
windows.h>
#pragmacoment(lib,"
ws2_32.lib"
usingnamespacestd;
classCSocketFrame
public:
intstart_up();
intclean_up();
intset_address(char*hname,char*sname,structsockaddr_in*sap,char*protocol);
intquit(SOCKETs);
SOCKETtcp_server(ULONGuIP,USHORTuPort);
SOCKETtcp_server(char*hname,char*sname);
SOCKETtcp_client(char*hname,char*sname);
SOCKETtcp_client(ULONGuIP,USHORTuPort);
};
intCSocketFrame:
:
start_up(void)
WORDwVersionRequested;
WSADATAwsaData;
wVersionRequested=MAKEWORD(2,2);
iResult=WSAStartup(wVersionRequested,&
wsaData);
=0)
WSAStartup调用错误,错误号:
%d\n"
return-1;
}
/*
if(LOBYTE(wsaData.wVersion!
=2||HIBYTE(wsaData.wVersion)!
=2))
无法找到可用的WSD版本\n"
WSACleanup();
//告诉用户无法找到可用的WSD
else
WS2.2初始化成功!
}*/
return0;
clean_up(void)
iResult=WSACleanup();
if(iResult==SOCKET_ERROR)
//WSACleanup()调用失败
WSACleanup调用错误,错误号:
Winsocketdll释放成功!
);
set_address(char*hname,char*sname,structsockaddr_in*sap,char*protocol)
structservent*sp;
structhostent*hp;
char*endptr;
unsignedshortport;
unsignedlongulAddr=INADDR_NONE;
//将地址结构socketsddr_in初始化为0,并将地址族设为AF_INET
memset(sap,0,sizeof(*sap));
sap->
sin_family=AF_INET;
if(hname!
=NULL)
//如果hname不为空,转化地址格式
ulAddr=inet_addr(hname);
if(ulAddr==INADDR_NONE||ulAddr==INADDR_ANY)
//调用错误,调用gethostbyname获得主机地址
hp=gethostbyname(hname);
if(hp==NULL)
{
未知的主机名,错误号:
}
sap->
sin_addr=*(structin_addr*)hp->
h_addr;
sin_addr.S_un.S_addr=ulAddr;
//如果调用者没有指明一个主机名或地址,则设为通配地址
sap->
sin_addr.s_addr=htonl(INADDR_ANY);
//尝试转换sname为一个整数
port=(unsignedshort)strtol(sname,&
endptr,0);
if(*endptr=='
//如果成功转化为网络字节序
sin_port=htons(port);
//如果失败,则假定是一个服务名称,通过getservbyname()函数获得端口号
sp=getservbyname(sname,protocol);
if(sp==NULL)
未知服务,错误号:
}
sin_port=sp->
s_port;
quit(SOCKETs)
intiResult=0;
iResult=closesocket(s);
printf("
closesocket调用错误,错误号:
iResult=clean_up();
SOCKETCSocketFrame:
tcp_server(char*hname,char*sname)
SOCKETListenSocket;
sockaddr_inlocal;
constinton=1;
//为服务器的本机地址设置用户输入的地址以及端口号
if(set_address(hname,sname,&
local,(char*)"
tcp"
)!
//创建套接字
ListenSocket=socket(AF_INET,SOCK_STREAM,0);
if(ListenSocket==INVALID_SOCKET)
socket函数调用错误,错误号:
WSACleanup();
return-1;
//绑定服务器地址
iResult=bind(ListenSocket,(structsockaddr*)&
local,sizeof(local));
if(iResult==-1)
bind函数调用错误!
错误号:
closesocket(ListenSocket);
//设置函数为监听状态,监听队列长度为NLISTEN
iResult=listen(ListenSocket,SOMAXCONN);
Listen函数调用错误!
quit(ListenSocket);
returnListenSocket;
tcp_server(ULONGuIP,USHORTuPort)
SOCKETListenSocket=INVALID_SOCKET;
memset(&
local,0,sizeof(local));
local.sin_family=AF_INET;
local.sin_addr.S_un.S_addr=htonl(uIP);
local.sin_port=htons(uPort);
clean_up();
tcp_client(char*hname,char*sname)
structsockaddr_inpeer;
SOCKETClientSocket;
//为服务器的地址peer设置用户输入的地址以及端口号
peer,(char*)"
ClientSocket=socket(AF_INET,SOCK_STREAM,0);
if(ClientSocket==INVALID_SOCKET)
//请求建立连接
iResult=connect(ClientSocket,(structsockaddr*)&
peer,sizeof(peer));
connect函数调用错误!
quit(ClientSocket);
returnClientSocket;
tcp_client(ULONGuIP,USHORTuPort)
peer,0,sizeof(peer));
peer.sin_family=AF_INET;
peer.sin_addr.S_un.S_addr=htonl(uIP);
peer.sin_port=htons(uPort);
#endif
【实验中出现问题及解决方法】
问题1:
如何获取文件长度
解决:
运用fseek(),ftell(),rewind()进行文件长度的获取。
问题2:
如何发送一个整型数据,主要是文件长度?
利用sprintf()函数,将数字写到发送区(字符数组)。
问题3:
几个发送字符数组发送后,接收方接收发生干扰的问题?
利用用一个发送字符数组,其他数组只做辅助使用。
用sprintf()函数,将数组合并。
【思考问题】
为什么有几个发送数组时,发送时没有错误,但是在接收时,会发生干扰?
:
这个问题还在思考,没有得出成熟的答案。
【实验体会】
这次利用定长与变长流式套接字实现了一个相对完整的功能,感觉还是相当不错的,学到了很多具体的东西,像在前面提到过的几个函数的使用。
以及进一步加深了对文件操作使用的理解。
最重要的是对在实际的操作之中,锻炼了发现问题解决问题的能力。
因为解决的问题比较实际,在网络上的资料搜集中,有很多解决问题的方法,在实验的过程中,不断地去尝试,行不通,再去换解决方案(如果看我的原始代码的话,会有比较明显的体现,我把那些行不通的方案都注释掉了,都可以看见!
)。
在这之中也学到了很多的知识。
成绩
优
良
中
及格
不及格
教师签名:
日期:
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 利用 套接 实现 文件 传输