使用socket函数的一些常见错误

1.socket

SOCKET socket( int af, int type, int protocol );

af(地址族):常为AF_INET 
使用AF_ISO等其他地址族标识,而非AF_INET。 
返回:-1。 
错误:10047(使用了与请求的协议不兼容的地址)

type(socket类型):通常为SOCK_STREAM或SOCK_DGRAM 
头文件中定义的只有如下几种标准类型: 
#define SOCK_STREAM 1 
#define SOCK_DGRAM 2 
#define SOCK_RAW 3 
#define SOCK_RDM 4 
#define SOCK_SEQPACKET 5 
使用非如上定义的类型。 
返回:-1。 
错误:10044(在这个地址家族中不存在对指定的插槽类型的支持)

protocol:通常为0

type = SOCK_STREAM,protocol = 6 
正常

type = SOCK_STREAM,protocol = 7 
返回:-1 
错误号:10043(请求的协议还没有在系统中配置,或者没有它存在的迹象)

type = SOCK_DGRAM,protocol = 17 
正常

type = SOCK_DGRAM,protocol = 19 
返回:-1 
错误号:10043(请求的协议还没有在系统中配置,或者没有它存在的迹象)

结论

  1. Socket暂时只支持AF_INET协议族。
  2. 对非标准的套接字类型不支持。
  3. 协议号参数可以为0,则使用与套接字类型相应的协议号;否则,协议号参数必须与相应的套接字类型相同。

2.bind

int bind( SOCKET s, const struct sockaddr FAR* name, int namelen );

s:在没有用socket申请资源的套接字上操作。 
返回:-1 
错误号:10038(在一个非套接字上尝试了一个操作)

name:通常使用AF_INET地址族、INADDR_ANY(0)地址

  1. 在local结构中,sin_family成员赋值为AF_OSI, 
    返回: -1 
    错误码:10047(使用了与请求的协议不兼容的地址)
  2. 在local结构中,sin_addr成员赋值为本计算机的IP地址,
  3. 在local结构中,sin_addr成员赋值为非本计算机的IP地址,如同小组的另一个同学的IP地址; 
    返回: -1 
    错误码:10049( 在其上下文中,该请求的地址无效)
  4. 在local结构中,sin_port成员赋值为135; 
    返回: -1 
    错误码:10048(通常每个套接字地址(协议/网络地址/端口)只允许使用一次)

namelen:通常为name所指的结构的大小,如sizeof(SOCKADDR_IN)

  1. namelen = 10 
    返回: -1 
    错误码:10014(系统检测到在一个调用中尝试使用指针参数时的无效指针地址)
  2. namelen = 16 
    返回: 0 
    正常
  3. namelen = 40 
    返回: 0 
    正常

结论

  1. 可以bind本机拥有的地址(或INADDR_ANY),非本机拥有的地址出错。
  2. bind已经被占用的端口值会出错。
  3. len参数要大于等于地址结构实际上所占的长度。

思考

  1. 因为本机可以有多个IP,所以需要有方法指出从哪个实体接收数据。
  2. 当然,提供一种表达“从所有实体接收”的方法是必要的。
  3. 在头文件中INADDR_ANY被明确定义为0。
  4. 关于bind已占用的端口。是指端口被bind,并且上层还是活的。(不设置复用)处于TIME-WAIT状态的端口表面上是被占用,实际上是可以bind成功的,但connect会失败。详见关于TIME-WAIT的笔记,第六条。

3.listen

int listen(SOCKET s, int backlog);


使用尚未半相关的套接字。(未成功bind的) 
返回:-1 
错误号:10022(提供了一个无效的参数)

backlog 
纯引用一段:(无出处)

“windows套接字实现中最多只允许服务器同时监听5个套接字。使用参数0,则系统将把该参数改为1,而使用超过5的值,系统将自动把该参数改为5。”

  设置参数值为0,有1个客户机可同时与服务器连接(在vista下有时有2个可以连接,有时有3个可以连接,-_0//)设置参数值为1,有1个客户机可同时与服务器连接设置参数值为10,有10个客户机可同时与服务器连接

结论

  1. 第一个参数的套接字必须是成功bind过后的。
  2. 监听个数为0的话,会自动设置为1。
  3. 最大监听个数在XP SP3下可以超过5。

问题

  1. 如何获得实际的backlog值? 
    MSDN: There is no standard provision to obtain the actual backlog value.

  2. 如何结束套接字的监听状态? 
    首先,close掉是可以的。如果不close呢?最初猜想backlog为0,-1等特殊值可以达到此效果,结果失败。求解。

4.accept

SOCKET accept( SOCKET s, struct sockaddr FAR* addr, int FAR* addrlen );


在没有listen的套接字上面。 
返回:-1 
错误号:10022(提供了一个无效的参数)

addr,输出参数,一般不填 

单机测试,填上本机的IP和某个端口号。 
结果:无法限制所接收的地址,执行完后addr中存放实际的地址。

addrlen 
同bind

结论

  1. 主套接字必须处于监听状态。
  2. 在地址字段填上任何值不能限制接受的连接。
  3. len参数要求所携带的值大于等于16。(AF_INET地址结构的长度)

5.recv

int recv( SOCKET s, char FAR* buf, int len, int flags ); 

对于服务器,一般是ns = accept(s , &addr , &len) ;

s,一般是用上面accept正常返回的值

  1. 在没有accept的从套接字上操作。(上面的ns) 
    返回:-1 
    错误号:10038(在一个非套接字上尝试了一个操作)

  2. 在主套接字上操作。(上面的s) 
    返回:-1 
    错误号:10057(由于套接字没有连接并且 
    (当使用一个 sendto 调用发送数据报套接字时)没有提供地址,发送或接收数据的请求没有被接受。 )

buf,要求指向一个有效的缓冲区 
如果指向的无效的内存区域 
返回: -1 
错误号:10014(系统检测到在一个调用中尝试使用指针参数时的无效指针地址)

len,发送的字节数 
len过长可能造成缓冲区溢出。 
这个属于编程中的普遍考虑问题,不是socket函数特有。

flags,一般用0 
设置MSG_PEEK标志后,接收但不移除数据。 (再次接收可得到相同的数据)

结论

  1. 对服务器来说,必须传递成功accept之后返回的套接字
  2. 缓冲区指针所指位置必须有效。
  3. 缓冲区长度参数不可超过实际准备的缓冲区长度。
  4. MSG_PEEK标志在接收的时候将保留数据。

6.send

int send( SOCKET s, const char FAR* buf, int len, int flags );

s,同recv

  1. 在没有accept的从套接字上操作。(上面的ns) 
    返回:-1 
    错误号:10038(在一个非套接字上尝试了一个操作)

  2. 在主套接字上操作。(上面的s) 
    返回:-1 
    错误号:10057(由于套接字没有连接并且 
    (当使用一个 sendto 调用发送数据报套接字时)没有提供地址, 
    发送或接收数据的请求没有被接受。 )

buf 
必须指向有效缓冲区,同recv

len 
必须和要发送的数据长度一致。

结论 
除flag可选项不同外,和recv一致。

7.closesocket

int closesocket( SOCKET s );

s

  1. 在申请套接字资源(调用socket)之前closesocket 
    返回: -1 
    错误号:10038(在一个非套接字上尝试了一个操作)

  2. 再已经closesocket的套接字上closesocket 
    返回: -1 
    错误号:10038(在一个非套接字上尝试了一个操作)

结论 

s必须是有效打开的套接字。 
不得重复关闭。

8.connect

int connect( SOCKET s, const struct sockaddr FAR* name, int namelen );

没有对端响应的情况 
在没有运行服务器的情况下,connect是否会一直阻塞? 
结果:等待一定时间后返回错误。 
返回: -1 
错误码:10061(由于目标机器积极拒绝,无法连接)


没有使用过bind的套接字。 
成功连接。 
产生隐式绑定,相关应用的详细资料。

name 
使用一些特殊的地址来测试。

  1. 使用远端点IP地址为INADDR_ANY测试。 
    返回:-1 
    错误号:10049(在其上下文中,该请求的地址无效)

  2. 使用远端点IP地址为10.1.1.255广播地址。 
    返回: -1 
    错误号:10060(由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败)

namelen 
同bind等需要传递地址结构长度的函数

结论

  1. 服务器必须启动listen。
  2. 可以不建立本地半相关,则进行隐式绑定。
  3. 客户不可以与INADDR_ANY主动相连,立即返回报错。
  4. 客户不可以与广播地址连接,会等待很久,返回失败。

讨论 

10060和10061两种错误不同。 
其中10061解释为目标机器积极拒绝,返回错误很快(秒级)。 
10060的情况,返回错误需要很长时间(几十秒级)。 
此处值得深入研究,两种情况下的抓包应该不一样。

9.recvfrom

int recvfrom( SOCKET s, char FAR* buf, int len, int flags, struct sockaddr FAR* from, int FAR* fromlen );

缺少半相关 
在没有bind的套接字上面,直接recvfrom。 
返回:-1 
错误号:10022(提供了一个无效的参数)

填写from结构 
向其中填入非对端使用的地址或端口。 
正常接收,并且from内置对端地址信息。

结论 

必须先进行本地半相关,指定端口,才能够接收。 
无法通过recvfrom的地址结构限制接收的地址和端口。

10.sendto

int sendto( SOCKET s, const char FAR* buf, int len, int flags, const struct sockaddr FAR* to, int tolen );

缺少半相关 
在没有bind的套接字上面,直接sendto。 
成功。返回发送的数据个数。

不存在的对端实体

  1. sendto到一个不存在的实体(to结构) 
    返回:发送的字符数 
    错误号:无

  2. 紧接着调用recvfrom 
    结果:没有阻塞,直接返回 
    返回:-1 
    错误号:10054 (远程主机强迫关闭了一个现有的连接。)

结论

  1. 可以在未本地半相关的情况下发送数据。由系统随机选择端口。

  2. 可以向不存在的远端点发送数据,本地仍然报告发送的字节数(不管有没有人接收)。

  3. 一般情况下,没有数据的时候recvfrom会阻塞。但是当给不存在的对端发送过数据后,会收到错误报告,紧接着的一次recvfrom会立即返回失败。(后面的仍然阻塞)

思考

  1. SOCK_DGRAM类型的服务,无法为用户确保数据的正常交付。但是通过recvfrom返回的错误,可以对发送情况作出一定的判断。

  2. 这也启示在使用SOCK_DGRAM时候的编程框架要考虑下,当recvfrom错误的时候,判断一下错误号,再进一步处理。

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
作者和贡献者 I. 入门指引 1. 简介 2. 简明教程 II. 安装与配置 3. 安装前需要考虑的事项 4. Unix 系统下的安装 5. Mac OS X 系统下的安装 6. Windows 系统下的安装 7. PECL 扩展库安装 8. 还有问题? 9. 运行配置 III. 语言参考 10. 基本语法 11. 类型 12. 变量 13. 常量 14. 表达式 15. 运算符 16. 流程控制 17. 函数 18. 类与对象(PHP 4) 19. 类与对象(PHP 5) 20. 异常处理 21. 引用的解释 IV. 安全 22. 简介 23. 总则 24. 以 CGI 模式安装 25. 以 Apache 模块安装 26. 文件系统安全 27. 数据库安全 28. 错误告 29. 使用 Register Globals 30. 用户提交的数据 31. 魔术引号 32. 隐藏 PHP 33. 保持更新 V. 特点 34. 用 PHP 进行 HTTP 认证 35. cookies 36. 会话 37. 处理 XForms 38. 文件上传处理 39. 使用远程文件 40. 连接处理 41. 数据库永久连接 42. 安全模式 43. PHP 的命令行模式 VI. 函数参考 I. .NET 函数 II. Advanced PHP debugger III. Alternative PHP Cache IV. Apache 特有函数 V. Array 数组函数 VI. Aspell 函数(已废弃) VII. BC math 高精度数学函数 VIII. Bzip2 压缩函数 IX. Calendar 日历函数 X. CCVS API Functions [deprecated] XI. Character Type Functions XII. Classes/Objects 类/对象函数 XIII. Classkit Functions XIV. ClibPDF Functions XV. COM 和 .Net(Windows)函数 XVI. Crack Functions XVII. Credit Mutuel CyberMUT functions XVIII. CURL, Client URL Library Functions XIX. Cybercash Payment Functions XX. Cyrus IMAP administration Functions XXI. Database (dbm-style) Abstraction Layer Functions XXII. Date/Time 日期/函数 XXIII. DB++ Functions XXIV. dBase Functions XXV. DBM Functions [deprecated] XXVI. dbx Functions XXVII. Direct IO Functions XXVIII. Directory 目录函数 XXIX. DOM Functions XXX. DOM XML Functions XXXI. Error Handling and Logging Functions XXXII. Exif Functions XXXIII. File Alteration Monitor Functions XXXIV. filePro Functions XXXV. Filesystem 文件系统函数 XXXVI. Firebird/InterBase Functions XXXVII. Firebird/Interbase Functions (PDO_FIREBIRD) XXXVIII. Forms Data Format Functions XXXIX. FriBiDi Functions XL. FrontBase Functions XLI. FTP 函数 XLII. Function Handling Functions XLIII. Gettext XLIV. GMP Functions XLV. GNU Readline XLVI. GNU Recode Functions XLVII. HTTP 函数 XLVIII. Hyperwave API Functions XLIX. Hyperwave Functions L. IBM DB2, Cloudscape and Apache Derby Functions LI. ICAP Functions [deprecated] LII. iconv Functions LIII. ID3 Functions LIV. IIS Administration Functions LV. Image 图像函数 LVI. IMAP, POP3 and NNTP Functions LVII. Informix Functions LVIII. Ingres II Functions LIX. IRC Gateway Functions LX. KADM5 LXI. LDAP Functions LXII. libxml Functions LXIII. Lotus Notes Functions LXIV. LZF Functions LXV. Mail Functions LXVI. mailparse Functions LXVII. Math 数学函数 LXVIII. MaxDB PHP Extension LXIX. MCAL Functions LXX. Mcrypt Encryption Functions LXXI. MCVE Payment Functions LXXII. Memcache Functions LXXIII. Mhash Functions LXXIV. Microsoft SQL Server and Sybase Functions (PDO_DBLIB) LXXV. Microsoft SQL Server Functions LXXVI. Mimetype Functions LXXVII. Ming functions for Flash LXXVIII. Miscellaneous Functions LXXIX. mnoGoSearch Functions LXXX. Mohawk Software Session Handler Functions LXXXI. mSQL Functions LXXXII. Multibyte String Functions LXXXIII. muscat Functions LXXXIV. MySQL 函数 LXXXV. MySQL Functions (PDO_MYSQL) LXXXVI. MySQL Improved Extension LXXXVII. Ncurses Terminal Screen Control Functions LXXXVIII. Network Functions LXXXIX. Net_Gopher XC. NSAPI-specific Functions XCI. Object Aggregation/Composition Functions XCII. Object property and method call overloading XCIII. ODBC and DB2 functions (PDO_ODBC) XCIV. ODBC Functions (Unified) XCV. oggvorbis XCVI. OpenAL Audio Bindings XCVII. OpenSSL Functions XCVIII. Oracle 函数 XCIX. Oracle Functions (PDO_OCI) C. Oracle 函数(已废弃) CI. Output Control 输出控制函数 CII. Ovrimos SQL Functions CIII. Paradox File Access CIV. Parsekit Functions CV. PDF functions CVI. PDO Functions CVII. PHP / Java Integration CVIII. PHP bytecode Compiler CIX. PHP Options&Information CX. POSIX Functions CXI. PostgreSQL 数据库函数 CXII. PostgreSQL Functions (PDO_PGSQL) CXIII. PostgreSQL Session Save Handler CXIV. PostScript document creation CXV. Printer Functions CXVI. Process Control Functions CXVII. Program Execution Functions CXVIII. Pspell Functions CXIX. qtdom Functions CXX. Radius CXXI. Rar Functions CXXII. Perl 兼容正则表达式函数 CXXIII. POSIX 扩展正则表达式函数 CXXIV. runkit Functions CXXV. SDO Functions CXXVI. SDO Relational Data Access Service Functions CXXVII. SDO XML Data Access Service Functions CXXVIII. Secure Shell2 Functions CXXIX. Semaphore, Shared Memory and IPC Functions CXXX. SESAM Database Functions CXXXI. Session Handling Functions CXXXII. Shared Memory Functions CXXXIII. Shockwave Flash Functions CXXXIV. SimpleXML functions CXXXV. SNMP 函数 CXXXVI. SOAP Functions CXXXVII. Socket Functions CXXXVIII. SQLite Functions CXXXIX. SQLite Functions (PDO_SQLITE) CXL. Standard PHP Library (SPL) Functions CXLI. Stream Functions CXLII. String 字符串处理函数 CXLIII. Sybase Functions CXLIV. TCP Wrappers Functions CXLV. Tidy Functions CXLVI. Tokenizer Functions CXLVII. Unicode Functions CXLVIII. URL 函数 CXLIX. Variable 变量函数 CL. Verisign Payflow Pro Functions CLI. vpopmail Functions CLII. W32api 函数 CLIII. WDDX Functions CLIV. xattr Functions CLV. xdiff Functions CLVI. XML 语法解析函数 CLVII. XML-RPC 函数 CLVIII. XMLReader functions CLIX. XSL functions CLX. XSLT Functions CLXI. YAZ Functions CLXII. YP/NIS Functions CLXIII. Zip File Functions (Read Only Access) CLXIV. Zlib Compression Functions VII. PHP 和 Zend 引擎内部资料 44. PHP 扩展库编程 API 指南 45. Zend API:深入 PHP 内核 46. 扩展 PHP 3 VIII. FAQ:常见问题 47. 一般信息 48. 邮件列表 49. 获取 PHP 50. 数据库问题 51. 安装常见问题 52. 编译问题 53. 使用 PHP 54. PHP 和 HTML 55. PHP 和 COM 56. PHP 和其它语言 57. 从 PHP/FI 2 移植到 PHP 3 58. 从 PHP 3 移植到 PHP 4 59. 从 PHP 4 移植到 PHP 5 60. 杂类问题 IX. 附录 A. PHP 及其相关工程的历史 B. 从 PHP 4 移植到 PHP 5 C. 从 PHP 3 移植到 PHP 4 D. 从 PHP/FI 2 移植到 PHP 3 E. PHP 的调试 F. 配置选项 G. php.ini 配置选项 H. 扩展库分类 I. 函数别名列表 J. 保留字列表 K. 资源类型列表 L. 支持的协议/封装协议列表 M. 可用过滤器列表 N. 所支持的套接字传输器(Socket Transports)列表 O. PHP 类型比较表 P. 解析器代号列表 Q. 关于本手册 R. 开放出版许可协议 S. 函数索引

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值