流式套接字并发服务器
主线程:
创建套接字并将其绑定到服务器所使用的熟知地址上。 重复调用accept接收客户端的请求,并且创建子线程处理响应。
子线程:
在线程创建时接收连接请求; 用该连接与客户端进行交互:接收请求并发回应答; 关闭连接并退出。子线程在处理完来自一个客户端的所有请求后退出
#include <winsock2.h> #include <windows.h> #define NETWORK1_2_1_A_COMM_H #define NETWORK1_2_1_A_COMM_H #include <stdio.h> #include <stdlib.h> #include <inaddr.h> #include <time.h> #include <string.h> #pragma comment(lib, "ws2_32.lib") #define MAXLINE 4096 // 接收缓冲区长度 #define LISTENQ 1024 // 监听队列长度 #define SEVER_PORT 13131 // 端口 //初始化动态连接库 int startUp() { WORD w_version = MAKEWORD(2, 2); WSADATA wsa_data; int res = WSAStartup(w_version, &wsa_data); if (res != 0) { printf("WSAStartup Error:%d\n",WSAGetLastError()); return -1; } if (LOBYTE(wsa_data.wVersion) != 2 || HIBYTE(wsa_data.wVersion) != 2) { printf("版本号错误:%d\n",WSAGetLastError()); WSACleanup(); return -1; } return 0; //WSAStartup()成功 } /*释放动态连接库*/ int cleanUp() { int res = WSACleanup(); if (res == SOCKET_ERROR) { printf("WSACleanup error:%d\n",WSAGetLastError()); return -1; } return 0; } /*断开连接并释放资源*/ int closeConn(SOCKET sock_conn) { int res = closesocket(sock_conn); //关闭连接 if (res == SOCKET_ERROR) { printf("close socket error:%d",WSAGetLastError()); return -1; } res = cleanUp(); return res; } /*Server Init*/ SOCKET tcpServerInit(u_short port) { int res = -1; // 设置地址 sockaddr_in server_addr; memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = htonl(INADDR_ANY); server_addr.sin_port = htons(port); //创建流式套接字 SOCKET sock_listen = socket(AF_INET, SOCK_STREAM, 0); if (sock_listen == INVALID_SOCKET) { printf("Sock error:%d",WSAGetLastError()); WSACleanup(); return -1; } //绑定服务器地址 res = bind(sock_listen, (struct sockaddr *)&server_addr, sizeof(server_addr)); if (res == SOCKET_ERROR) { printf("bind error:%d\n",WSAGetLastError()); closeConn(sock_listen); return -1; } //设置服务器为监听状态 最长长度LISTENQ res = listen(sock_listen, LISTENQ); if (res == SOCKET_ERROR) { printf("listen error:%d\n",WSAGetLastError()); closeConn(sock_listen); return -1; } return sock_listen; } /*线程函数*/ void *asyncTcpEchoServer(LPVOID pParam) { int sock_res; char recv_data[MAXLINE]; // 将输入参数转换成连接套接字 SOCKET sock_conn = *((SOCKET *)pParam); do { memset(recv_data, 0, MAXLINE); // 接收数据 sock_res = recv(sock_conn, recv_data, MAXLINE, 0); if (sock_res > 0) { printf("从客户端接收到的数据:%s\n",recv_data); // 回射接收的数据 sock_res = send(sock_conn, recv_data, sock_res, 0); if (sock_res == SOCKET_ERROR) { printf("send error:%s\n",WSAGetLastError()); sock_res = -1; } else { printf("发送的数据为:%s\n",recv_data); } } else { if (sock_res == 0) { puts("客户端关闭"); } else { printf("recv error :%d\n",WSAGetLastError()); sock_res = -1; } break; } } while (sock_res > 0); if (sock_res == -1) { puts("连接失败"); } return NULL; } int main(int argc, char *argv[]) { int res = -1; SOCKET sock_conn; SOCKET sock_listen; //pthread_t pThread; HANDLE hThread; char buff[MAXLINE]; //缓冲区 // 启动 res = startUp(); if (res == -1) return -1; //监听 sock_listen = tcpServerInit(SEVER_PORT); if (sock_listen == -1) return -1; puts("Server StartUp seccess!"); while (true) { //接受客户端连接请求,返回连接套接字sock_conn sock_conn = accept(sock_listen, NULL, NULL); if (sock_conn != INVALID_SOCKET) { puts("连接成功"); // 创建线程 hThread=CreateThread(NULL,0,asyncTcpEchoServer,&sock_conn,0,NULL); //pthread_create(&pThread, nullptr, asyncTcpEchoServer, &sock_conn); } else { printf("accept error:%d\n",WSAGetLastError()); closeConn(sock_listen); return -1; } } CloseHandle(hThread); Sleep(100); // 关闭连接 closeConn(sock_listen); return 0; }