套接字传输文件的试验

来源:互联网 发布:网络大V发布谣言 编辑:程序博客网 时间:2024/06/06 00:12
 

原先对文件总是有一种莫名的抗拒,原因未知,最近做东西的时候需要用套接字传送文件、图片之类的东西,没办法,只好硬着头皮上了。

做了一个小实验,下面是几点心得:

(1)网上查了一些资料,发现其实套接字传送文件和传输文字没什么区别的,因为它只负责发送和接收,而对到底是什么样类型的数据是并不感冒的(以字节为单位传输)

(2)发送文件时,需要先把文件以二进制格式打开,读取到内存中,然后再发送;

(3)接收文件时,需要先读进内存中,然后再以二进制格式写到文件中;

(4)传输时,为了保证传输的可靠性,必须遵循TCP协议;

实验只是基本实现功能,可能在安全性和准确性方面欠缺,有高手路过的话请指正,不甚感激!

用到的几个文件操作函数:

(1) fopen()、fclose()  分别是打开和关闭文件;

(2)fread()、fwrite()  分别是读、写文件;

(3)feof() 判断是否到了文件尾;

实验的主要功能是:客户端向服务器发送图片

代码如下:

客户端代码:

/*Arthur: Bai YongHui*//*Data: 2011.11.04*//*功能:客户端,给服务器发送图片*/#include <stdio.h>#include<iostream.h>#include <winsock2.h>#include "initSock.h"void main() {CinitSock initSock;    FILE * fp=NULL;    if((fp=fopen("1.jpg","rb"))==NULL)    {        printf("cannot open file\n");        return;    }    SOCKET sendSock = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );    if ( sendSock == INVALID_SOCKET ) {printf( "Error at socket(): %ld\n", WSAGetLastError() );return;    }    sockaddr_in srvAddr;srvAddr.sin_family = AF_INET;srvAddr.sin_addr.S_un.S_addr = inet_addr( "127.0.0.1" );    srvAddr.sin_port = htons( 2035 );if (connect( sendSock, (SOCKADDR*) &srvAddr, sizeof(srvAddr) ) == SOCKET_ERROR) {printf( "Failed to connect.\n" );return;}int nSend=0;char sendBuf[1024]={0};while(1){int nRead = fread(sendBuf, 1024, 1, fp);if(nRead<1 && ferror(fp)!=0){printf("failed to read file\n");return;}nSend = send( sendSock, sendBuf, 1024, 0 );if( nSend == SOCKET_ERROR ){printf("the connection to server has been failed\n");return;}printf( "success to send %d bytes\n", nSend );if(feof(fp)){printf("success to transmit file to server\n");break;}}closesocket(sendSock);fclose(fp);}

服务器代码:

/*Arthur: Bai YongHui*//*Data: 2011.11.04*//*功能:服务器,用于接收来自客户端发送的图片*/#include <stdio.h>#include<iostream.h>#include <winsock2.h>#include<string.h>#include "initSock.h"void main() {CinitSock initSock;    SOCKET lstnSock = socket( AF_INET, SOCK_STREAM, 0);    if ( lstnSock == INVALID_SOCKET ) {       printf( "failed to create socket\n" );       return;        }sockaddr_in bindAddr;bindAddr.sin_family = AF_INET;bindAddr.sin_addr.S_un.S_addr = inet_addr( "127.0.0.1" );bindAddr.sin_port = htons(2035);int addrLen=sizeof(SOCKADDR);    if ( bind( lstnSock, (SOCKADDR*) &bindAddr, addrLen ) == SOCKET_ERROR ) {printf( "failed to bind\n" );closesocket(lstnSock);return;}    if ( listen( lstnSock, 5 ) == SOCKET_ERROR ){      printf( "failed to listen\n");  return;}SOCKET commSock=INVALID_SOCKET;commSock =  accept( lstnSock, NULL, NULL );if(commSock != INVALID_SOCKET )printf( "Client connected to Server\n" );char recvbuf[1024]={0};    FILE *fp;if((fp=fopen("recv.jpg","wb+"))==NULL)    {        printf("cannot open file\n");return;    }while(1){int nRecv = recv( commSock, recvbuf, 1024, 0 );if( nRecv == SOCKET_ERROR ){printf("connection to client has been failed\n");return;}else if( nRecv == 0 ){printf( "success to receive faile from client\n" );break;}int nWrite=fwrite(recvbuf,1024,1,fp);if( nWrite<1 && ferror(fp)!=0 ){printf( "failed to write file\n" );return;}}closesocket(commSock);closesocket(lstnSock);fclose(fp);}