socket通信中send()返回-1问题解析

之前在代码测试中发现以下问题:
socket通信中,client连续发送大包(约500KB/每包)数据到server,期间偶尔出现send()返回-1,打印errno对应问题,显示为:No such file or directory。
问题分析:
每次出现问题时,设置的send的长度为40960,但实际上一次send的长度小于40960,如40460,即一包40960的数据在send时未完全copy到发送缓冲区,剩余460数据在继续copy时发生异常。
分析原因可能是,第一次拷贝的时候的发送缓冲区可用空间小于40960,则仅拷贝40460,此时发送缓冲区已经满了,且在继续拷贝剩余460字节数据时,发送缓冲区还未释放相应长度空间,所以造成数据拷贝失败,即send返回-1.
问题验证:
第一次send返回结果ret>0,且ret≠40960时,延时3ms,然后继续;
经测试,不再返回-1,40960数据能完整发送;
问题改进:
调用linux提供的ioctl(fd, SIOCOUTQ, &count)方法来查询socket的发送缓冲区(write buffer)当前占用量是否为0,若为0则表示之前的数据已经发送完成,然后继续发送剩余部分数据。这样就可以将固定延时替换并控制。之后重新测试,问题得以解决。

参考连接:https://blog.csdn.net/thwack/article/details/79960935

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
unit uMain; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Mask, RzEdit, RzButton, ExtCtrls, IniFiles, RzTabs, ComCtrls, RzListVw, RzShellCtrls, ImgList, RzShellDialogs, RzCmboBx, QRCtrls, QuickRpt, jpeg, ShlObj, RzPanel, RzSplit, RzTreeVw, DB, ADODB, Provider, DBClient, GridsEh, DBGridEh, RzStatus; type PShellItem = ^TShellItem; TShellItem = record FullID, ID: PItemIDList; Empty: Boolean; DisplayName, TypeName: string; ImageIndex, Size, Attributes: Integer; ModDate: string; end; TfrmMain = class(TForm) RzPageControl1: TRzPageControl; TabSheet1: TRzTabSheet; TabSheet2: TRzTabSheet; lbl1: TLabel; edt_Path1: TRzEdit; btn_o2: TButton; Button1: TButton; SplPreview: TRzSplitter; img1: TImage; RzToolbar1: TRzToolbar; RzSpacer1: TRzSpacer; ClientDS_PicCap: TClientDataSet; DataSP_PicCap: TDataSetProvider; Qry_PicCap: TADOQuery; Ds_PicCap: TDataSource; DBGridEh1: TDBGridEh; ClientDataSetH: TClientDataSet; DataSetProviderH: TDataSetProvider; QueryH: TADOQuery; DataSourceH: TDataSource; RzBtn_0: TRzBitBtn; RzBtn_1: TRzBitBtn; ImageList1: TImageList; Memo1: TMemo; ClientDS_PicCapacc_id_only: TStringField; ClientDS_PicCapname: TStringField; ClientDS_PicCapplate_num: TStringField; ClientDS_PicCapplate_type: TStringField; ClientDS_PicCapInsDate: TDateTimeField; ClientDS_PicCapAcc_ID_Only_1: TStringField; ClientDS_PicCapfDateTime: TDateTimeField; ClientDS_PicCapPicturePath1: TStringField; ClientDS_PicCapPicturePath2: TStringField; ClientDS_PicCapPicturePath3: TStringField; ClientDS_PicCapPicturePath4: TStringField; ClientDS_PicCapPicturePath5: TStringField; ClientDS_PicCapPicturePath6: TStringField; ClientDS_PicCapPicturePath7: TStringField; ClientDS_PicCapPrintCount: TIntegerField; ClientDataSetHAutoID: TAu

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值