原先對文件總是有一種莫名的抗拒,原因未知,最近做東西的時候需要用套接字傳送文件、圖片之類的東西,沒辦法,只好硬着頭皮上了。
做了一個小實驗,下面是幾點心得:
(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);
- }