select连接TCPIP数据收发测试
2014-11-23 18:44
471 查看
下面给出一个简单的select模型的服务端套接字,非阻塞模式。连接1个客户端,接收100MB数据后,返回OK退出。
发送端:
下面给出一个简单的select模型的服务端套接字,非阻塞模式。连接1个客户端,接收100MB数据后,返回OK退出。
//服务端,接收端 int SelectTcpRecver1() { SOCKET sListen, sClient; int iAddrSize; //HANDLE hThread;DWORD dwThreadId; struct sockaddr_in local, client; iAddrSize = sizeof(client); sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); if (sListen == SOCKET_ERROR) { printf("socket() failed: %d\n", WSAGetLastError()); return 1; } local.sin_addr.s_addr = htonl(INADDR_ANY); local.sin_family = AF_INET; local.sin_port = htons(TCPSERVER_PORT); if (bind(sListen, (struct sockaddr *)&local, sizeof(local)) == SOCKET_ERROR) { printf("bind() failed: %d\n", WSAGetLastError()); return -11; } if (listen(sListen, 8)) { printf("listen Error:%d\n", WSAGetLastError()); return -2; } //ULONG NonBlock = 1; //if (ioctlsocket(sListen, FIONBIO, &NonBlock) == SOCKET_ERROR){ // printf("ioctlsocket() failed with error %d\n", WSAGetLastError()); // return -3; //} printf("进入监听状态\n"); int loopi = 0; timeval tv; FD_SET SelectSet; while (1) { FD_ZERO(&SelectSet);//初始化fd_set FD_SET(sListen, &SelectSet);//分配套接字句柄到相应的fd_set tv.tv_sec = 2;//这里我们打算让select等待两秒后返回,避免被锁死,也避免马上返回 tv.tv_usec = 0; select(0, &SelectSet, NULL, NULL, &tv); loopi++; if (FD_ISSET(sListen, &SelectSet))//如果套接字句柄还在fd_set里,说明客户端已经有connect的请求发过来了,马上可以accept成功 { sClient = accept(sListen, (struct sockaddr *)&client, &iAddrSize); if (sClient == INVALID_SOCKET){ printf("accept() failed: %d\n", WSAGetLastError()); break; } else { printf("Accepted client: %s:%d\n", inet_ntoa(client.sin_addr), ntohs(client.sin_port)); break; } } else//还没有客户端的connect请求,我们可以去做别的事,避免像没有用select方式的阻塞套接字程序被锁死的情况,如果没用select,当程序运行到accept的时候客户端恰好没有connect请求,那么程序就会被锁死,做不了任何事情 { printf("wait ......%d\r",loopi); //::MessageBox(NULL, "waiting...", "recv", MB_ICONINFORMATION);//别的事做完后,继续去检查是否有客户端连接请求 } } char * Buffer = (char *)malloc(MB100); if (NULL == Buffer) { printf("100MB 内存分配失败!\n"); return -1; } DWORD nRemainRecv = MB100; char * pBuf = (char *)Buffer; int len,ret; //接收100MB的数据 while (nRemainRecv > 0) { len = recv(sClient, pBuf, nRemainRecv, 0); if (len < 0){ printf("Recv HeadDate Fail:%d\n", len); break; } else if (len == 0){ printf("Pre len is 0 client quit!\n"); break; } printf("接收数据:%d\n", len); nRemainRecv -= len; pBuf += len; } free(Buffer); printf("共接收数据:%d\n", MB100); char szBuff[8]; sprintf_s(szBuff, _countof(szBuff), "%s", "OK"); ret = send(sClient, szBuff, (int)strlen(szBuff), 0); if (ret == 0)printf("send 0\n"); else if (ret == SOCKET_ERROR) { printf("send() failed: %d\n", WSAGetLastError()); } closesocket(sClient); closesocket(sListen); return 0; }
发送端:
int TcpSender() { SOCKET sClient; int ret; struct sockaddr_in server; struct hostent *host = NULL; sClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (sClient == INVALID_SOCKET) { printf("socket() failed: %d\n", WSAGetLastError()); return 1; } ZeroMemory(&server, sizeof(sockaddr_in)); server.sin_family = AF_INET; server.sin_port = htons(TCPSERVER_PORT); server.sin_addr.s_addr = inet_addr(ServerIp); if (server.sin_addr.s_addr == INADDR_NONE) { host = gethostbyname(ServerIp); if (host == NULL) { printf("Unable to resolve server: %s\n", ServerIp); return 1; } CopyMemory(&server.sin_addr, host->h_addr_list[0],host->h_length); } printf("We are trying to connect to %s:%d...\n", inet_ntoa(server.sin_addr), htons(server.sin_port)); if (connect(sClient, (struct sockaddr *)&server,sizeof(server)) == SOCKET_ERROR) { printf("connect() failed: %d\n", WSAGetLastError()); return 1; } //准备发送100MB的数据 char * Buffer = (char *)malloc(MB100); if (NULL == Buffer) { printf("100MB 内存分配失败!\n"); return -1; } memset(Buffer, '#', MB100); int nLeft = MB100; int idx = 0; DWORD lt1, lt2,lt; int i = 0; lt1 = timeGetTime(); //int len1 = 65535; while (nLeft > 0) { lt2 = timeGetTime(); /* if (nLeft > len1)len1 = 65536; else len1 = nLeft;*/ //Sleep(5); ret = send(sClient, &Buffer[idx], nLeft, 0); if (ret == 0){ printf("send is 0,%d\n", WSAGetLastError()); break; } else if (ret == SOCKET_ERROR) { printf("send() failed: %d\n", WSAGetLastError()); break; } lt = timeGetTime() - lt2; //if(lt > 50) printf("i:%d,Send %d bytes,耗时:%d\n",i, ret,lt); i++; nLeft -= ret; idx += ret; } printf("100MB 发送完成:%d\n", timeGetTime() - lt1); //接收确认的信息 char szBuf[8]; ret = recv(sClient, szBuf, sizeof(szBuf), 0); if (ret == 0){ printf(" Graceful close\n"); } else if (ret == SOCKET_ERROR) { printf("recv() failed: %d,共计消耗时间%d\n", WSAGetLastError(),timeGetTime() - lt2); } else { szBuf[ret] = '\0'; printf("RECV [%d bytes]: '%s'\n", ret, szBuf); printf("接收确认信息:%d\n", timeGetTime() - lt2); } free(Buffer); closesocket(sClient); return 0; }
相关文章推荐
- select连接TCPIP数据收发测试(连接多客户)
- C# TCP/IP 连接实现数据收发 Demo (Visual Studio)
- Cisco测试命令和TCP/IP连接故障处理
- Cisco测试命令和TCP/IP连接故障处理
- 第5章 Cisco测试命令和TCP/IP连接故障处理
- 第5章 Cisco测试命令和TCP/IP连接故障处理
- Netstat用于显示与IP、TCP、UDP和ICMP协议相关的统计数据,一般用于检验本机各端口的网络连接情况
- Cisco测试命令和TCP/IP连接故障处理
- Android扫描局域网内IP并建立Socket连接,和PC服务端收发数据
- (原创)TCPIP的二次封装,可同时多客户端收发数据
- 简单的JAVA TCP/IP连接测试
- Java TCP/IP字节流在本地进行数据传输测试
- Netstat用于显示与IP、TCP、UDP和ICMP协议相关的统计数据,一般用于检验本机各端口的网络连接情况
- Qt实现TcpClient和TcpServer连接收发数据
- 建立tcp/ip连接,vc6实现客户端(发送数据)
- Cisco测试命令和TCP/IP连接故障处理
- 使用Java的TCP/Ip创建本地测试连接
- AT指令建立TCP/IP 链接,并自收发数据
- 数据连接linux网络编程之TCP/IP基础(四):TCP连接的建立和断开、滑动窗口
- vc socket api建立TCP连接(包括域名解析)并收发数据的代码模板