主頁 > 軟體工程 > 為什么檔案傳輸之前先要發送一個OK資訊

為什么檔案傳輸之前先要發送一個OK資訊

2020-09-14 17:11:20 軟體工程

我看了任何檔案傳輸程式,在傳輸檔案之前接收方都要發送一個OK資訊,發送方收到OK資訊之后才能發送。我把發送接收OK資訊的代碼去掉就不能完整地傳輸檔案呢?下面是我的示例程式,大家能分析下是為什么嗎
發送方
#include "stdafx.h"
#include<iostream.h>
#include<winsock2.h>
#include <stdio.h>
#pragma comment(lib,"ws2_32.lib")
int main(){
WSADATA wsaData;
if(WSAStartup(MAKEWORD(2,2), &wsaData)) //初始化WinSock協議堆疊
{ cout<<"Winsock不能被初始化!";
WSACleanup();
return 0;
}
SOCKET sockSer, sockConn; //注意服務器端必須創建兩個套接字
sockSer=socket(AF_INET,SOCK_STREAM,0);  //初始化套接字
SOCKADDR_IN addrSer,addrCli;  //注意服務器端要創建兩個套接字地址
addrSer.sin_family=AF_INET;
addrSer.sin_port=htons(5566);
addrSer.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");

bind(sockSer,(SOCKADDR*)&addrSer,sizeof(SOCKADDR));   //系結套接字
listen(sockSer,5);

int len=sizeof(SOCKADDR);
cout<<"服務器等待客戶端的連接……"<<endl;

sockConn=accept(sockSer,(SOCKADDR*)&addrCli,&len);  //接受連接,注意回傳值
if(sockConn==INVALID_SOCKET){
cout<<"服務器接受客戶端連接失敗!"<<endl;
return 0;}
else cout<<"服務器接受客戶端連接成功!"<<endl;

char fileName[256]="C:\\cf.jpg";

char filebuf[1000],OK[3],fsize[50];
/***打開要傳輸的檔案***/
FILE *fp; //創建檔案指標
if((fp=fopen(fileName,"rb"))==NULL) { //以只讀位元組型模式打開檔案
cout << "不能打開檔案: " << fileName << endl;
closesocket(sockConn);    //關閉socket,對方等待的recv()函式將回傳0
closesocket(sockSer); WSACleanup();
return 0; } //檔案打開失敗則退出
/***獲取檔案長度***/
fseek(fp,0L,SEEK_END);     //將檔案的位置指標移到檔案末尾
long int size=ftell(fp);   //獲取當前檔案位置指標值,該值即為檔案長度
fseek(fp,0L,SEEK_SET);     //將檔案的位置指標移到檔案開頭
long int fileSize=size;
//fileSize = htonl(size);  //將檔案長度存入結構變數fileMsg
itoa(fileSize,fsize,10);
send(sockConn, fsize, strlen(fsize)+1, 0); //發送fileName
cout<<fsize;
/***接收對方發送來的OK資訊***/
if (recv(sockConn, OK, sizeof(OK), 0) <= 0) {
cout << "接收OK失敗,程式退出!\n";
closesocket(sockSer); WSACleanup();
return 0; }

/***發送檔案內容***/

if (strcmp(OK, "OK") == 0) {
while(!feof(fp))   { //當檔案沒有到末尾時   

size=fread(filebuf,1,sizeof(filebuf),fp); //每次讀1000位元組
send(sockConn, filebuf, size, 0); //每次寫size個位元組
}
cout << "檔案發送完畢"; //顯示傳輸完成
fclose(fp); } //關閉檔案



closesocket(sockSer);
WSACleanup();
return 0; }

接收方

#include "stdafx.h"
#include<iostream.h>
#include<winsock2.h>
#include <stdio.h>
#include  "direct.h"  //_mkdir()函式需要
#pragma comment(lib,"ws2_32.lib")
int main(){
WSADATA wsaData;
if(WSAStartup(MAKEWORD(2,2), &wsaData)) {
cout<<"Winsock不能被初始化!";
WSACleanup();
return 0; }
SOCKET sockCli;  //創建套接字sockCli
sockCli=socket(AF_INET,SOCK_STREAM,0);

SOCKADDR_IN addrSer;  //客戶端只要創建一個套接字地址
addrSer.sin_family=AF_INET;
addrSer.sin_port=htons(5566);
addrSer.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");

int res=connect(sockCli,(SOCKADDR*)&addrSer, sizeof(SOCKADDR));
if(res){ cout<<"客戶端連接服務器失敗"<<endl;
return -1; }
else{ cout<<"客戶端連接服務器成功"<<endl; }
char sendbuf[256], recvbuf[256];

long int filelen;
 char filedir[200]= "D:\\TANG\\"; //指定接收到的檔案的保存目錄
  char ok[3]="OK",fsize[50];
char fileBuffer[1000];//接收檔案資料的緩沖區
/***創建檔案的保存目錄***/
_mkdir(filedir); //_mkdir()用于創建檔案夾
/***接收檔案名及檔案長度資訊***/
if((filelen=recv(sockCli,fsize,sizeof(fsize),0))<=0){
cout<<"未接收到檔案名字及檔案長度!\n";
closesocket(sockCli); WSACleanup();
        return 0; }
filelen=atol(fsize);
 /***創建檔案準備接收檔案內容***/
char filename[256]="e:\\cf.jpg";
FILE *fp; //創建檔案指標
if((fp=fopen(filename,"wb"))==NULL) {//以只寫方式打開檔案
cout<<"不能打開檔案:"<<filename<<endl;
closesocket(sockCli);
WSACleanup();
return 0; } //檔案打開失敗則退出
cout<<filelen;
send(sockCli,ok,sizeof(ok),0); //發送接收檔案資料的確認資訊
  /***接收檔案資料并寫入檔案***/
 long int size=0;  //接收到的資料長度
  do   {    
size=recv(sockCli,fileBuffer,sizeof(fileBuffer),0);
fwrite(fileBuffer,1,size,fp); //寫入檔案,每次寫size位元組
filelen-=size;
}while(size!=0  && filelen>0);  //回圈條件是size!=0 && filelen>0
    /***檔案傳輸完成結束程式***/   
    cout<<"接收檔案"<<filename<<"完畢!\n";
    fclose(fp);

while(1){
cout<<"客戶端說:>";
cin>>sendbuf;
if(strcmp(sendbuf,"bye")==0){
break;}
send(sockCli,sendbuf,strlen(sendbuf)+1,0);
if(recv(sockCli,recvbuf,256,0)>0)
cout<<"服務器說:>"<<recvbuf<<endl;
else {cout<<"服務器已關閉連接"<<endl;
break;}
}
closesocket(sockCli);
WSACleanup();
return 0;
}

uj5u.com熱心網友回復:

個人理解 就是用Ok做了個簡單的分界協議

uj5u.com熱心網友回復:


可以去掉。直接發檔案。

uj5u.com熱心網友回復:

去掉了,直接發檔案會出錯,接收到的檔案少了幾Kb。

uj5u.com熱心網友回復:

接收端接收到檔案長度以后,按這個長度來回圈recv接收后續的資料。

uj5u.com熱心網友回復:

參考 4 樓 Eleven 的回復:
接收端接收到檔案長度以后,按這個長度來回圈recv接收后續的資料。
我是說發送OK標記的作用,發送檔案長度的作用,那我倒是知道的

uj5u.com熱心網友回復:

你不會加斷點除錯嗎?

uj5u.com熱心網友回復:

這就是神秘莫測的協議

uj5u.com熱心網友回復:

我用VC6,確實不知道怎么加斷點除錯。

uj5u.com熱心網友回復:

學習研究一下

uj5u.com熱心網友回復:

這和它們之間的協議有關吧

uj5u.com熱心網友回復:

我發現異步接收檔案的程式,可不需要發送和接收OK資訊

uj5u.com熱心網友回復:

請問你這個程式怎么運行?小白不懂,同一專案下,兩個.c檔案都有main函式,怎么運行?

uj5u.com熱心網友回復:

了解下檔案傳輸協議Xmodem,Ymodem。接收者是根據協議決議資料的。

uj5u.com熱心網友回復:

參考 12 樓 索尼與三星 的回復:
請問你這個程式怎么運行?小白不懂,同一專案下,兩個.c檔案都有main函式,怎么運行?

要建立兩個專案,一個是服務器端,一個客戶端,才能相互通信

uj5u.com熱心網友回復:

我這個不異步通信的檔案傳輸程式確實不需要發送OK訊息,也可以收發檔案。所以我猜想發送OK資訊,可能是為了隔斷前面的發送檔案大小/檔案名 和后面的 發送 檔案內容, 使 前 后的發送資料不會發送粘包現象,我這只是猜想,不知道如何證實。

uj5u.com熱心網友回復:

我這個 異步通信的檔案傳輸程式
https://download.csdn.net/download/wuxia2118/11522767

uj5u.com熱心網友回復:

你剛開始學,還是想辦法先除錯起來,還有一個簡單或者傻的辦法,就是發送任何資料之前先發送一個整數的長度,表示下來要發送多長的資料塊,接收的時候先接收4個位元組的整數長度,然后就知道剩余還有多少資料需要接收,在回圈接收完剩余的資料就行。
char szBuf[1024]  ={0};
strcpy(szBuf,filebuf,size);
int iDataSize= size;
send(sock,(char*)&iDataSize,sizeof(iDataSize),0);
send(sock,szBuf,iDataSize,0);

接收端:
int iDataSize= 0;
char szBuf[1024]  ={0};
int iRet = recv(sock,(char*)&iDataSize,sizeof(iDataSize),0);
if(iRet ==sizeof(iDataSize))
{
     int iTotalRecvLen = 0;
     while(iTotalRecvLen <iDataSize)
     {
          iRet = recv(sock,szBuf+,iDataSize-iTotalRecvLen,0);
          if(iRet<=0)
                break;
          iTotalRecvLen+=iRet;
     }
}

我博客里寫了一套開源的通信框架,你有空可以看看,不過對你來講,可能比較復雜。
https://blog.csdn.net/moonbamboo/article/details/99286765

uj5u.com熱心網友回復:

參考 3 樓 wuxia2118 的回復:
去掉了,直接發檔案會出錯,接收到的檔案少了幾Kb。


不可能的,發送OK不是必須的,完全可以去掉,只要明確檔案發送的起點及終點(可以指明檔案長度)

uj5u.com熱心網友回復:

請問,windows上的IO重定向,可以直接把打開的檔案描述符定向到socket描述符嗎

轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/37108.html

標籤:網絡編程

上一篇:CString Format問題

下一篇:vba小白求教!請問這道求債券現值的代碼哪里有問題?

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • Git本地庫既關聯GitHub又關聯Gitee

    創建代碼倉庫 使用gitee舉例(github和gitee差不多) 1.在gitee右上角點擊+,選擇新建倉庫 ? 2.選擇填寫倉庫資訊,然后進行創建 ? 3.服務端已經準備好了,本地開始作準備 (1)Git 全域設定 git config --global user.name "成鈺" git c ......

    uj5u.com 2020-09-10 05:04:14 more
  • CODING DevOps 代碼質量實戰系列第二課,相約周三

    隨著 ToB(企業服務)的興起和 ToC(消費互聯網)產品進入成熟期,線上故障帶來的損失越來越大,代碼質量越來越重要,而「質量內建」正是 DevOps 核心理念之一。**《DevOps 代碼質量實戰(PHP 版)》**為 CODING DevOps 代碼質量實戰系列的第二課,同時也是本系列的 PHP ......

    uj5u.com 2020-09-10 05:07:43 more
  • 推薦Scrum書籍

    推薦Scrum書籍 直接上干貨,推薦書籍清單如下(推薦有順序的哦) Scrum指南 Scrum精髓 Scrum敏捷軟體開發 Scrum捷徑 硝煙中的Scrum和XP : 我們如何實施Scrum 敏捷軟體開發:Scrum實戰指南 Scrum要素 大規模Scrum:大規模敏捷組織的設計 用戶故事地圖 用 ......

    uj5u.com 2020-09-10 05:07:45 more
  • CODING DevOps 代碼質量實戰系列最后一課,周四發車

    隨著 ToB(企業服務)的興起和 ToC(消費互聯網)產品進入成熟期,線上故障帶來的損失越來越大,代碼質量越來越重要,而「質量內建」正是 DevOps 核心理念之一。 **《DevOps 代碼質量實戰(Java 版)》**為 CODING DevOps 代碼質量實戰系列的最后一課,同時也是本系列的 ......

    uj5u.com 2020-09-10 05:07:52 more
  • 敏捷軟體工程實踐書籍

    Scrum轉型想要做好,第一步先了解并真正落實Scrum,那么我推薦的Scrum書籍是要看懂并實踐的。第二步是團隊的工程實踐要做扎實。 下面推薦工程實踐書單: 重構:改善既有代碼的設計 決議極限編程 : 擁抱變化 代碼整潔代碼 程式員的職業素養 修改代碼的藝術 撰寫可讀代碼的藝術 測驗驅動開發 : ......

    uj5u.com 2020-09-10 05:07:55 more
  • Jenkins+svn+nginx實作windows環境自動部署vue前端專案

    前面文章介紹了Jenkins+svn+tomcat實作自動化部署,現在終于有空抽時間出來寫下Jenkins+svn+nginx實作自動部署vue前端專案。 jenkins的安裝和配置已經在前面文章進行介紹,下面介紹實作vue前端專案需要進行的哪些額外的步驟。 注意:在安裝jenkins和nginx的 ......

    uj5u.com 2020-09-10 05:08:49 more
  • CODING DevOps 微服務專案實戰系列第一課,明天等你

    CODING DevOps 微服務專案實戰系列第一課**《DevOps 微服務專案實戰:DevOps 初體驗》**將由 CODING DevOps 開發工程師 王寬老師 向大家介紹 DevOps 的基本理念,并探討為什么現代開發活動需要 DevOps,同時將以 eShopOnContainers 項 ......

    uj5u.com 2020-09-10 05:09:14 more
  • CODING DevOps 微服務專案實戰系列第二課來啦!

    近年來,工程專案的結構越來越復雜,需要接入合適的持續集成流水線形式,才能滿足更多變的需求,那么如何優雅地使用 CI 能力提升生產效率呢?CODING DevOps 微服務專案實戰系列第二課 《DevOps 微服務專案實戰:CI 進階用法》 將由 CODING DevOps 全堆疊工程師 何晨哲老師 向 ......

    uj5u.com 2020-09-10 05:09:33 more
  • CODING DevOps 微服務專案實戰系列最后一課,周四開講!

    隨著軟體工程越來越復雜化,如何在 Kubernetes 集群進行灰度發布成為了生產部署的”必修課“,而如何實作安全可控、自動化的灰度發布也成為了持續部署重點關注的問題。CODING DevOps 微服務專案實戰系列最后一課:**《DevOps 微服務專案實戰:基于 Nginx-ingress 的自動 ......

    uj5u.com 2020-09-10 05:10:00 more
  • CODING 儀表盤功能正式推出,實作作業資料可視化!

    CODING 儀表盤功能現已正式推出!該功能旨在用一張張統計卡片的形式,統計并展示使用 CODING 中所產生的資料。這意味著無需額外的設定,就可以收集歸納寶貴的作業資料并予之量化分析。這些海量的資料皆會以圖表或串列的方式躍然紙上,方便團隊成員隨時查看各專案的進度、狀態和指標,云端協作迎來真正意義上 ......

    uj5u.com 2020-09-10 05:11:01 more
最新发布
  • windows系統git使用ssh方式和gitee/github進行同步

    使用git來clone專案有兩種方式:HTTPS和SSH:
    HTTPS:不管是誰,拿到url隨便clone,但是在push的時候需要驗證用戶名和密碼;
    SSH:clone的專案你必須是擁有者或者管理員,而且需要在clone前添加SSH Key。SSH 在push的時候,是不需要輸入用戶名的,如果配置... ......

    uj5u.com 2023-04-19 08:41:12 more
  • windows系統git使用ssh方式和gitee/github進行同步

    使用git來clone專案有兩種方式:HTTPS和SSH:
    HTTPS:不管是誰,拿到url隨便clone,但是在push的時候需要驗證用戶名和密碼;
    SSH:clone的專案你必須是擁有者或者管理員,而且需要在clone前添加SSH Key。SSH 在push的時候,是不需要輸入用戶名的,如果配置... ......

    uj5u.com 2023-04-19 08:35:34 more
  • 2023年農牧行業6大CRM系統、5大場景盤點

    在物聯網、大資料、云計算、人工智能、自動化技術等現代資訊技術蓬勃發展與逐步成熟的背景下,數字化正成為農牧行業供給側結構性變革與高質量發展的核心驅動因素。因此,改造和提升傳統農牧業、開拓創新現代智慧農牧業,加快推進農牧業的現代化、資訊化、數字化建設已成為農牧業發展的重要方向。 當下,企業數字化轉型已經 ......

    uj5u.com 2023-04-18 08:05:44 more
  • 2023年農牧行業6大CRM系統、5大場景盤點

    在物聯網、大資料、云計算、人工智能、自動化技術等現代資訊技術蓬勃發展與逐步成熟的背景下,數字化正成為農牧行業供給側結構性變革與高質量發展的核心驅動因素。因此,改造和提升傳統農牧業、開拓創新現代智慧農牧業,加快推進農牧業的現代化、資訊化、數字化建設已成為農牧業發展的重要方向。 當下,企業數字化轉型已經 ......

    uj5u.com 2023-04-18 08:00:18 more
  • 計算機組成原理—存盤器

    計算機組成原理—硬體結構 二、存盤器 1.概述 存盤器是計算機系統中的記憶設備,用來存放程式和資料 1.1存盤器的層次結構 快取-主存層次主要解決CPU和主存速度不匹配的問題,速度接近快取 主存-輔存層次主要解決存盤系統的容量問題,容量接近與價位接近于主存 2.主存盤器 2.1概述 主存與CPU的聯 ......

    uj5u.com 2023-04-17 08:20:31 more
  • 談一談我對協同開發的一些認識

    如今各互聯網公司普通都使用敏捷開發,采用小步快跑的形式來進行專案開發。如果是小專案或者小需求,那一個開發可能就搞定了。但對于電商等復雜的系統,其功能多,結構復雜,一個人肯定是搞不定的,所以都是很多人來共同開發維護。以我曾經待過的商城團隊為例,光是后端開發就有七十多人。 為了更好地開發這類大型系統,往 ......

    uj5u.com 2023-04-17 08:18:55 more
  • 專案管理PRINCE2核心知識點整理

    PRINCE2,即 PRoject IN Controlled Environment(受控環境中的專案)是一種結構化的專案管理方法論,由英國政府內閣商務部(OGC)推出,是英國專案管理標準。
    PRINCE2 作為一種開放的方法論,是一套結構化的專案管理流程,描述了如何以一種邏輯性的、有組織的方法,... ......

    uj5u.com 2023-04-17 08:18:51 more
  • 談一談我對協同開發的一些認識

    如今各互聯網公司普通都使用敏捷開發,采用小步快跑的形式來進行專案開發。如果是小專案或者小需求,那一個開發可能就搞定了。但對于電商等復雜的系統,其功能多,結構復雜,一個人肯定是搞不定的,所以都是很多人來共同開發維護。以我曾經待過的商城團隊為例,光是后端開發就有七十多人。 為了更好地開發這類大型系統,往 ......

    uj5u.com 2023-04-17 08:18:00 more
  • 專案管理PRINCE2核心知識點整理

    PRINCE2,即 PRoject IN Controlled Environment(受控環境中的專案)是一種結構化的專案管理方法論,由英國政府內閣商務部(OGC)推出,是英國專案管理標準。
    PRINCE2 作為一種開放的方法論,是一套結構化的專案管理流程,描述了如何以一種邏輯性的、有組織的方法,... ......

    uj5u.com 2023-04-17 08:17:55 more
  • 計算機組成原理—存盤器

    計算機組成原理—硬體結構 二、存盤器 1.概述 存盤器是計算機系統中的記憶設備,用來存放程式和資料 1.1存盤器的層次結構 快取-主存層次主要解決CPU和主存速度不匹配的問題,速度接近快取 主存-輔存層次主要解決存盤系統的容量問題,容量接近與價位接近于主存 2.主存盤器 2.1概述 主存與CPU的聯 ......

    uj5u.com 2023-04-17 08:12:06 more