上一篇说了函数,这一篇主要叙述main:
//创建用于监听的套接字
SOCKET sockSrv = socket(AF_INET, SOCK_STREAM, 0);//ipv4协议,流式传输
SOCKADDR_IN addrSrv;//此数据结构用做bind、connect、recvfrom、sendto等函数的参数,指明地址信息。
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(port); //1024以上的端口号
addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY); //INADDR_ANY 代表任意ip
//绑定套接字
int retVal = bind(sockSrv, (LPSOCKADDR)&addrSrv, sizeof(SOCKADDR_IN));
if (retVal == SOCKET_ERROR) {
printf("Failed bind:%d\n", WSAGetLastError());
return 0;
}
if (listen(sockSrv, 10) == SOCKET_ERROR) {//10代表允许连接的个数
printf("Listen failed:%d", WSAGetLastError());
return 0;
}
SOCKADDR_IN addrClient;
int len = sizeof(SOCKADDR);
会一直在while里面等待客户端的连接,一旦客户端连接上了,就会分配一个线程给它接收消息,然后在setClient里面这个线程会再开一个子线程发送消息给客户端。这是服务器与客户端的连接。
int i = 0;
while (1)
{
//等待客户请求到来
sockConn[i] = accept(sockSrv, (SOCKADDR *)&addrClient, &len);//会阻塞进程,直到有客户端连接上来为止
if (sockConn[i] == SOCKET_ERROR) {
printf("Accept failed:%d", WSAGetLastError());
break;
}
pthread_t tids[10];
int res = pthread_create(&tids[i], NULL, setClient, (void*)&sockConn[i]);
if (res != 0) //创建线程成功返回0
{
cout << "pthread_create error:error_code=" << res << endl;
}
i++;
}
closesocket(sockSrv);