关于socket send recv 两个函数各种错误说明
来源:互联网 发布:数据库软件哪个好 编辑:程序博客网 时间:2024/06/04 08:33
首先吐槽以下微软的socket的两个最重要的API:send函数和recv函数,本菜鸟感觉这两个函数是用来给程序员自己开发的函数,用起来跟翔一样的体验。
int recv( _In_ SOCKET s, _Out_ char *buf, _In_ int len, _In_ int flags);
int send( _In_ SOCKET s, _In_ const char *buf, _In_ int len, _In_ int flags);
这是这两个函数的原型,参数含义我就不解释了,这里面常见的两种错误:
1、发送长度问题。这是个老生常谈的问题,在send一串字符的时候应该首先发送这串字符的长度n,然后才能在recv的时候recv(HANDLE , recvstring , n , 0);
2、还是发送长度的问题。在现实程序中发现一个问题,当发送长度过大时候,经常一次recv不够完全,需要多次recv才能接收完全,经常发现send 10000个字符,recv返回的接收字符串长度小于10000。这时候就应该这样写
int cSocket::SendBits(char * s , int bytes){int sendbytes = 0;while(sendbytes < bytes) //实际发送长度小于应该发送长度</span>{sendbytes+= send( hSocket , (char *)(s+sendbytes) , bytes-sendbytes , 0 );}return sendbytes;}int cSocket::RecvBits(char *& s , int bytes){int recvbytes = 0;while(recvbytes < bytes) //实际接收长度小于应该接收长度{recvbytes += recv( hSocket , s+recvbytes , bytes-recvbytes , 0 );}return recvbytes;}再来对比以下MSDN上面的例子
#define WIN32_LEAN_AND_MEAN#include <winsock2.h>#include <Ws2tcpip.h>#include <stdio.h>// Link with ws2_32.lib#pragma comment(lib, "Ws2_32.lib")#define DEFAULT_BUFLEN 512#define DEFAULT_PORT "27015"int __cdecl main() { //---------------------- // Declare and initialize variables. WSADATA wsaData; int iResult; SOCKET ConnectSocket = INVALID_SOCKET; struct sockaddr_in clientService; char *sendbuf = "this is a test"; char recvbuf[DEFAULT_BUFLEN]; int recvbuflen = DEFAULT_BUFLEN; //---------------------- // Initialize Winsock iResult = WSAStartup(MAKEWORD(2,2), &wsaData); if (iResult != NO_ERROR) { printf("WSAStartup failed: %d\n", iResult); return 1; } //---------------------- // Create a SOCKET for connecting to server ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (ConnectSocket == INVALID_SOCKET) { printf("Error at socket(): %ld\n", WSAGetLastError() ); WSACleanup(); return 1; } //---------------------- // The sockaddr_in structure specifies the address family, // IP address, and port of the server to be connected to. clientService.sin_family = AF_INET; clientService.sin_addr.s_addr = inet_addr( "127.0.0.1" ); clientService.sin_port = htons( 27015 ); //---------------------- // Connect to server. iResult = connect( ConnectSocket, (SOCKADDR*) &clientService, sizeof(clientService) ); if ( iResult == SOCKET_ERROR) { closesocket (ConnectSocket); printf("Unable to connect to server: %ld\n", WSAGetLastError()); WSACleanup(); return 1; } // Send an initial buffer iResult = send( ConnectSocket, sendbuf, (int)strlen(sendbuf), 0 ); if (iResult == SOCKET_ERROR) { printf("send failed: %d\n", WSAGetLastError()); closesocket(ConnectSocket); WSACleanup(); return 1; } printf("Bytes Sent: %ld\n", iResult); // shutdown the connection since no more data will be sent iResult = shutdown(ConnectSocket, SD_SEND); if (iResult == SOCKET_ERROR) { printf("shutdown failed: %d\n", WSAGetLastError()); closesocket(ConnectSocket); WSACleanup(); return 1; } // Receive until the peer closes the connection do { iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0); if ( iResult > 0 ) printf("Bytes received: %d\n", iResult); else if ( iResult == 0 ) printf("Connection closed\n"); else printf("recv failed: %d\n", WSAGetLastError()); } while( iResult > 0 ); // cleanup closesocket(ConnectSocket); WSACleanup(); return 0;}MSDN在处理recvbuf的时候任然没有判断iResult和recvbuflen之间的关系。为整个程序埋下了隐患。(其实在MSDN remark中有简单说明)真是坑啊。
0 0
- 关于socket send recv 两个函数各种错误说明
- 关于SOCKET中send和recv函数的说明收藏(转载)
- 关于Linux socket通讯中send,recv函数的一个说明
- socket recv和send函数
- 关于SOCKET中send和recv函数工作原理总结
- 关于SOCKET中send和recv函数工作原理总结
- 关于SOCKET中send和recv函数工作原理总结
- 关于SOCKET中send和recv函数工作原理总结
- 关于SOCKET中send和recv函数工作原理总结
- Socket send函数和recv函数详解
- Socket send函数和recv函数详解
- Socket send函数和recv函数详解
- Socket send函数和recv函数详解
- Socket send函数和recv函数详解
- Socket send函数和recv函数详解
- Socket send函数和recv函数详解
- Socket send函数和recv函数
- Socket send函数和recv函数详解
- weblogic创建教程
- selenium IDE ,明明存在元素,却找不到元素 ,报错Element not found
- 张小龙:警惕KPI和流程管理,鼓励小团队作战和轮岗
- 4种巧用“数字”激励用户行为的方法
- 录制语音4
- 关于socket send recv 两个函数各种错误说明
- 张勇:最好的投资是不断挑战自我
- 汇编指令CALL与JMP的区别
- dashboard web tools demonstration during Baidu Internship
- 【NOIP普及组】2016模拟考试(10.29)——海港的船只
- 我的学习!
- js获取键盘时间或禁止按键操作
- 关于idea maven web项目导入的步骤
- Navicat for SQLite 所有功能