《Socket C++ TCP阻塞 非阻塞总结》由会员分享,可在线阅读,更多相关《Socket C++ TCP阻塞 非阻塞总结(30页珍藏版)》请在金锄头文库上搜索。
1、0、可运行实例及基本知识1、如何设置socket函数的非阻塞调用?2、深入 CSocket 编程之阻塞和非阻塞模式3、SOCKET类的设计和实现 服务器#include stdafx.h#include #include #include #include #include #include #pragma comment(lib, ws2_32.lib)#define SERVPORT 7861 /*服务器监听端口号*/#define MAXDATASIZE 100#define BACKLOG 10using namespace std;std:vector client_fd;char
2、bufMAXDATASIZE; DWORD WINAPI qtPingServerThreadFunc(LPVOID lpThreadParameter);int _tmain(int argc, _TCHAR* argv)SOCKET sockfd; /*sock_fd:监听socket;client_fd:数据传输socket */ struct sockaddr_in my_addr; /* 本机地址信息*/ struct sockaddr_in remote_addr; /* 客户端地址信息*/ char szMsg=hello;WORD wVersionRequested;WSADA
3、TA wsaData;int err;wVersionRequested = MAKEWORD(2,0);err = WSAStartup(wVersionRequested,&wsaData);if (0 != err)coutSocket failed;return 0;if (LOBYTE(wsaData.wVersion)!= 2 | HIBYTE(wsaData.wVersion) != 0)WSACleanup();return 0;sockfd = socket(AF_INET,SOCK_STREAM,0);if (INVALID_SOCKET = sockfd)coutSoke
4、t Create Failed;return 0;/*sockfd = socket(AF_INET, SOCK_STREAM, 0);*/if (sockfd = -1) perror( socket创建出错!); exit(1); my_addr.sin_family=AF_INET; my_addr.sin_port=htons(SERVPORT); my_addr.sin_addr.s_addr = INADDR_ANY; memset( &(my_addr.sin_zero),0,8);if (bind(sockfd, (struct sockaddr *) &my_addr, si
5、zeof(struct sockaddr) = -1) perror( bind出错!);/exit(1); int n = 0;while(1) if (listen(sockfd, BACKLOG) != -1) int sin_size = sizeof(struct sockaddr_in); SOCKET nSocket = accept(sockfd, (struct sockaddr *) &remote_addr, &sin_size);std:vector:iterator itr_end = client_fd.end();std:vector:iterator itr =
6、 std:find(client_fd.begin(),itr_end,nSocket);if (itr = itr_end)client_fd.push_back(nSocket);printf( received a connection from %sn, inet_ntoa(remote_addr.sin_addr);DWORD dwPingThreadID;HANDLE hPingHandle = CreateThread(0, 0, qtPingServerThreadFunc, 0, 0, &dwPingThreadID); for (int n = 0;n client_fd.
7、size(); n+)closesocket(client_fdn); client_fd.clear(); DWORD WINAPI qtPingServerThreadFunc(LPVOID lpThreadParameter)while (1)for (int n = 0;n client_fd.size(); n+)int recvbytes;if (recvbytes=recv(client_fdn, buf, MAXDATASIZE, 0) !=-1) bufrecvbytes = 0; printf( Received: %d,%sn,n,buf);send(client_fdn
8、, buf, sizeof(buf), 0);return 0x1001;客户端:#include #pragma comment(lib, ws2_32.lib)using namespace std;#define SERVPORT 7861 /*服务器监听端口号*/#define DEST_IP 192.168.1.35#define MAXDATASIZE 100;int _tmain(int argc, _TCHAR* argv)int sockfd, recvbytes; char bufMAXDATASIZE; struct hostent *host; struct socka
9、ddr_in serv_addr; struct sockaddr_in dest_addr; /* 目的地址*/ WORD wVersionRequested;WSADATA wsaData;int err;wVersionRequested = MAKEWORD(2,0);err = WSAStartup(wVersionRequested,&wsaData);if (0 != err)couth_addr);*/serv_addr.sin_addr.s_addr = inet_addr(DEST_IP); memset( &(serv_addr.sin_zero),0,8);if (co
10、nnect(sockfd, (struct sockaddr *) &serv_addr, sizeof(struct sockaddr) = -1) perror(connect出错!);/exit(1);char szMsg = hao;int nlen = sizeof(serv_addr);int uIndex = 0;while (1)Sleep(1000);if (send(sockfd, Hello, are connected!n, 23, 0) = -1)coutWSAGetLastError()endl;elsecoutuIndex+:an TCP package is s
11、endedendl;if (recvbytes=recv(sockfd, buf, MAXDATASIZE, 0) !=-1) bufrecvbytes = 0; printf( Received: %s,buf);closesocket(sockfd); return 0;一.WinSock基本知识 这里不打算系统地介绍socket或者WinSock的知识。首先介绍WinSock API函数,讲解阻塞/非阻塞的概念;然后介绍socket的使用。1.WinSock API Socket接口是网络编程(通常是TCP/IP协议,也可以是其他协议)的API。最早的Socket接口是Berkeley接
12、口,在Unxi操作系统中实现。WinSock也是一个基于Socket模型的API,在Microsoft Windows操作系统类中使用。它在Berkeley接口函数的基础之上,还增加了基于消息驱动机制的Windows扩展函数。Winscok1.1只支持TCP/IP网络,WinSock2.0增加了对更多协议的支持。这里,讨论TCP/IP网络上的API。Socket接口包括三类函数:第一类是WinSock API包含的Berkeley socket函数。这类函数分两部分。第一部分是用于网络I/O的函数,如accept、Closesocket、connect、recv、recvfrom、Select、Send、Sendto另一部分是不涉及网络I/O、在本地端完成的函数,如bind、getpeername、getsockname、getsocketopt、htonl、htons、inet_addr、inet_ntonioctlsocket、listen、ntohl、ntohs、setsocketopt、shutdow、socket等第二类是检索有关域名、通