原先对文件总是有一种莫名的抗拒,原因未知,最近做东西的时候需要用套接字传送文件、图片之类的东西,没办法,只好硬着头皮上了。
做了一个小实验,下面是几点心得:
(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);
- }