怎么样通过VC++实现TCP服务器

怎么样通过VC++实现TCP服务器,第1张

.h文件

#pragma once

#define WIN32_LEAN_AND_MEAN

#define _WINSOCK_DEPRECATED_NO_WARNINGS

#include <mutex>

#include <thread>

#include <vector>

#include <stdio.h>

#include <tchar.h>

#include <Windows.h>

#include <WinSock2.h>

#pragma comment(lib,"ws2_32.lib")

#define DEFAULT_BUFLEN 512*128

#define MAX_CONNECTIONS 10

class sockServer

{

public:

sockServer(int port, char *(*callback)(void*))

bool sockSetup()

void sockStart()

void sockStop()

~sockServer()

private:

void serverThread()

void messageMonitor()

std::thread clientThread

std::thread servThread

std::mutex mutexLock

SOCKET clientSock[MAX_CONNECTIONS]

SOCKET listenSock

int connections

void *recData

void *senData

char *(*callback)(void*)

TCHAR errMsg[100]

int iSendResult

sockaddr_in sai

HANDLE hMutex

int iResult

bool active

WSADATA wd

int port

}

.cpp文件

#include "sockServer.h"

sockServer::sockServer(int port, char *(*callback)(void*))

{

active = false

connections = 0

this->port = port

this->callback = callback

}

bool sockServer::sockSetup()

{

// Trying to create a Mutex

hMutex = CreateMutex(NULL, TRUE, "{SOCKSERVER-BY-11MOON11}")

// Making sure no other instance of our mutex exists

if (GetLastError() == ERROR_ALREADY_EXISTS)

{

// One instance of our mutex already exists - exiting

printf("CreateMutex failed with error: %d\n", GetLastError())

printf("Server is already running!\n")

return false

}

// Setting up Winsock

iResult = WSAStartup(MAKEWORD(1, 1), &wd)

if (iResult != 0)

{

// Error setting up Winsock

_sntprintf_s(errMsg, sizeof(errMsg), "WSAStartup failed with error: %d", iResult)

return false

}

// Cleaning and setting up Socket Addr Information

ZeroMemory(&sai, sizeof(sai))

sai.sin_family = AF_INET

sai.sin_addr.s_addr = INADDR_ANY

sai.sin_port = htons(port)

// Allocating memory for reciving data and creating a socket

recData = (void *)VirtualAlloc(NULL, DEFAULT_BUFLEN, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE)

listenSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)

// Making sure socket started properly

if (listenSock == INVALID_SOCKET)

{

// Error occurred wile staring socket - exiting

printf("Socket failed with error: %ld\n", WSAGetLastError())

WSACleanup()

return false

}

// Binding information and starting listening for connections

bind(listenSock, (sockaddr*)&sai, sizeof(sai))

listen(listenSock, MAX_CONNECTIONS)

// We did it!

printf("Setup() was successfull!\n")

return true

}

void sockServer::sockStart()

{

if (!active)

{

printf("Starting server thread...\n")

active = true

servThread = std::thread(&sockServer::serverThread, this)

}

else

{

printf("Server thread is started already!\n")

}

}

void sockServer::sockStop()

{

if (active)

{

printf("Stopping server...\n")

active = false

closesocket(listenSock)

servThread.join()

clientThread.join()

printf("Server is stopped!\n")

}

else

{

printf("Server thread is not active!\n")

}

}

void sockServer::serverThread()

{

printf("Server thread is now active!\n")

clientThread = std::thread(&sockServer::messageMonitor, this)

for ( active == true Sleep(10))

{

printf("Waiting for a client to connect...\n")

clientSock[connections] = accept(listenSock, NULL, NULL)

if (active)

printf("Client #%d has connected!\n", connections)

if (clientSock[connections] == INVALID_SOCKET)

{

printf("Accept failed with error: %d\n", WSAGetLastError())

shutdown(clientSock[connections], SD_BOTH)

closesocket(listenSock)

WSACleanup()

}

mutexLock.lock()

connections++

mutexLock.unlock()

// When max limit of clients is reached - exit this loop

if (connections == MAX_CONNECTIONS)

{

break

}

}

}

void sockServer::messageMonitor()

{

for ( active == true Sleep(10))

{

for (int i = 0 i < connections i++)

{

mutexLock.lock()

iResult = recv(clientSock[i], reinterpret_cast<char *>(recData), DEFAULT_BUFLEN, 0)

if (iResult > 0)

{

printf("Bytes received: %d from client #%d\n", iResult, i)

senData = callback(recData)

iSendResult = send(clientSock[i], reinterpret_cast<char *>(senData), strlen(reinterpret_cast<char *>(senData)), 0)

if (iSendResult == SOCKET_ERROR)

{

printf("Send to client #%d failed with error: %d\n", i, WSAGetLastError())

printf("Closing connection #%d\n", i)

shutdown(clientSock[i], SD_SEND)

closesocket(clientSock[i])

}

printf("Bytes sent: %d\n", iSendResult)

}

VirtualFree(senData, 128, MEM_FREE)

memset(recData, 0, sizeof(void*))

memset(senData, 0, sizeof(void*))

mutexLock.unlock()

}

}

mutexLock.lock()

for (int i = 0 i < connections i++)

{

printf("Closing connection #%d\n", i)

shutdown(clientSock[i], SD_SEND)

closesocket(clientSock[i])

}

mutexLock.unlock()

WSACleanup()

}

sockServer::~sockServer()

{

delete[] &errMsg

delete[] recData

delete[] senData

ReleaseMutex(hMutex)

}

测试:

#define _CRT_SECURE_NO_WARNINGS

#define _WINSOCKAPI_

#include <Windows.h>

#include <iostream>

#include <string>

#include <thread>

#include "sockServer.h"

using namespace std

void handleServer()

typedef struct _PACKET

{

BYTE Operation

char Buffer[1024]

}PACKET, *PPACKET

#define MESSAGE 8

char *serverCallback(void *params)

{

printf("Callback function has been called\n")

char *response = (char *)VirtualAlloc(NULL, 64, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE)

switch (((PPACKET)params)->Operation)

{

case MESSAGE:

//MessageBox(NULL, ((PPACKET)params)->Buffer, NULL, MB_OK)

strcat(response, "A message has ben displayed!")

break

default:

strcat(response, "Error: Invalid command.")

break

}

return response

}

int main()

{

string command

sockServer sS(65533, &serverCallback)

if (sS.sockSetup())

sS.sockStart()

for ( true Sleep(10))

{

cin >> command

if (command == "stop")

{

sS.sockStop()

}

}

return 0

}

你的服务器端并没有一直去接收客户端发送的字符,所以发送一次就阻塞到了上面的重新建连接的地方了。__while(recv(sockConn,recvBuf,1000,0) >0) __{____printf("%s\n",recvBuf) ____ZeroMemory(recvBuf,sizeof(recvBuf))__}

做成这样的就行


欢迎分享,转载请注明来源:夏雨云

原文地址:https://www.xiayuyun.com/zonghe/280863.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-21
下一篇2023-04-21

发表评论

登录后才能评论

评论列表(0条)

    保存