0、可运行实例及基本知识
1、如何设置socket函数的非阻塞调用? 2、深入 CSocket 编程之阻塞和非阻塞模式 3、SOCKET类的设计和实现
服务器
#include \#include
#pragma comment(lib, \#define SERVPORT 7861 /*服务器监听端口号*/ #define MAXDATASIZE 100 #define BACKLOG 10 using namespace std;
std::vector
DWORD WINAPI qtPingServerThreadFunc(LPVOID lpThreadParameter); int _tmain(int argc, _TCHAR* argv[]) {
}
if (LOBYTE(wsaData.wVersion)!= 2 || HIBYTE(wsaData.wVersion) != 0) SOCKET sockfd; /*sock_fd:监听socket;client_fd:数据传输socket */
struct sockaddr_in my_addr; /* 本机地址信息*/ struct sockaddr_in remote_addr; /* 客户端地址信息*/ char szMsg[]=\; WORD wVersionRequested; WSADATA wsaData; int err;
wVersionRequested = MAKEWORD(2,0);
err = WSAStartup(wVersionRequested,&wsaData); if (0 != err) {
cout<<\; return 0;
{ }
sockfd = socket(AF_INET,SOCK_STREAM,0); if (INVALID_SOCKET == sockfd) { }
/*sockfd = socket(AF_INET, SOCK_STREAM, 0);*/ if (sockfd == -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, sizeof(struct sockaddr)) == -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
client_fd.push_back(nSocket);
printf( \a connection from %s\\n\, inet_ntoa(remote_addr.sin_addr)); DWORD dwPingThreadID;
HANDLE hPingHandle = CreateThread(0, 0, qtPingServerThreadFunc, 0, 0,
perror( \出错!\); //exit(1);
perror( \创建出错!\); exit(1);
cout<<\; return 0; WSACleanup(); return 0;
std::find(client_fd.begin(),itr_end,nSocket);
&dwPingThreadID);
}
DWORD WINAPI qtPingServerThreadFunc(LPVOID lpThreadParameter) { }
while (1) { }
return 0x1001;
for (int n = 0;n < client_fd.size(); n++) { }
int recvbytes;
if ((recvbytes=recv(client_fd[n], buf, MAXDATASIZE, 0)) !=-1) { }
buf[recvbytes] = '\\0';
printf( \,n,buf); send(client_fd[n], buf, sizeof(buf), 0);
}
for (int n = 0;n < client_fd.size(); n++) { }
client_fd.clear();
closesocket(client_fd[n]); }
}
客户端:
#include
#pragma comment(lib, %using namespace std;
#define SERVPORT 7861 /*服务器监听端口号*/ #define DEST_IP \#define MAXDATASIZE 100;
int _tmain(int argc, _TCHAR* argv[]) {
int sockfd, recvbytes; char buf[MAXDATASIZE]; struct hostent *host;
struct sockaddr_in serv_addr;
}
if (LOBYTE(wsaData.wVersion)!= 2 || HIBYTE(wsaData.wVersion) != 0) { }
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){ }
serv_addr.sin_family=AF_INET; serv_addr.sin_port=htons(SERVPORT);
serv_addr.sin_addr.s_addr = inet_addr(DEST_IP); memset( &(serv_addr.sin_zero),0,8);
if (connect(sockfd, (struct sockaddr *) &serv_addr, \\ }
char szMsg[] = \; int nlen = sizeof(serv_addr); int uIndex = 0; while (1) {
Sleep(1000);
if (send(sockfd, \, 23, 0) == -1) { } else {
cout< sizeof(struct sockaddr)) == -1) { perror(\出错!\); //exit(1); perror(\创建出错!\); exit(1); WSACleanup(); return 0; WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD(2,0); err = WSAStartup(wVersionRequested,&wsaData); if (0 != err) { cout<<\; return 0; struct sockaddr_in dest_addr; /* 目的地址*/ /* serv_addr.sin_addr = *((struct in_addr *)host->h_addr);*/ } return 0; } closesocket(sockfd); } if ((recvbytes=recv(sockfd, buf, MAXDATASIZE, 0)) !=-1) { } buf[recvbytes] = '\\0'; printf( \,buf); cout< 一.WinSock基本知识 这里不打算系统地介绍socket或者WinSock的知识。首先介绍WinSock API函数,讲解阻塞/非阻塞的概念;然后介绍socket的使用。 1.WinSock API Socket接口是网络编程(通常是TCP/IP协议,也可以是其他协议)的API。最早的Socket接口是Berkeley接口,在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_nton ioctlsocket、listen、ntohl、ntohs、setsocketopt、shutdow、socket等 第二类是检索有关域名、通信服务和协议等Internet信息的数据库函数,如