利用流式套接字实现文件的传输Word格式.docx

上传人:b****6 文档编号:17375327 上传时间:2022-12-01 格式:DOCX 页数:14 大小:18.70KB
下载 相关 举报
利用流式套接字实现文件的传输Word格式.docx_第1页
第1页 / 共14页
利用流式套接字实现文件的传输Word格式.docx_第2页
第2页 / 共14页
利用流式套接字实现文件的传输Word格式.docx_第3页
第3页 / 共14页
利用流式套接字实现文件的传输Word格式.docx_第4页
第4页 / 共14页
利用流式套接字实现文件的传输Word格式.docx_第5页
第5页 / 共14页
点击查看更多>>
下载资源
资源描述

利用流式套接字实现文件的传输Word格式.docx

《利用流式套接字实现文件的传输Word格式.docx》由会员分享,可在线阅读,更多相关《利用流式套接字实现文件的传输Word格式.docx(14页珍藏版)》请在冰豆网上搜索。

利用流式套接字实现文件的传输Word格式.docx

{

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()函数,将数组合并。

【思考问题】

为什么有几个发送数组时,发送时没有错误,但是在接收时,会发生干扰?

这个问题还在思考,没有得出成熟的答案。

【实验体会】

这次利用定长与变长流式套接字实现了一个相对完整的功能,感觉还是相当不错的,学到了很多具体的东西,像在前面提到过的几个函数的使用。

以及进一步加深了对文件操作使用的理解。

最重要的是对在实际的操作之中,锻炼了发现问题解决问题的能力。

因为解决的问题比较实际,在网络上的资料搜集中,有很多解决问题的方法,在实验的过程中,不断地去尝试,行不通,再去换解决方案(如果看我的原始代码的话,会有比较明显的体现,我把那些行不通的方案都注释掉了,都可以看见!

)。

在这之中也学到了很多的知识。

成绩

及格

不及格

教师签名:

日期:

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 小学教育 > 英语

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1