bigpotato

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

server

#include "stdafx.h"
#include <string>
#include <iostream>
#include <WinSock2.h>
#include <ws2tcpip.h>
#include <process.h>
#include <conio.h>

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

using namespace std;

void unicode2Ansi(const wchar_t *wsBuffer, char *szBuffer, int *nMultyLen = NULL);
unsigned int __stdcall listenProc(void *param);
unsigned int __stdcall requestProc(void *param);

struct SockInfo
{
    SOCKET sock;
    char addr[64];
    int port;
};

SOCKET g_sock;
SockInfo g_clients[FD_SETSIZE];
int g_totalCnt = 0;
bool g_bContinue = true;


int _tmain(int argc, _TCHAR* argv[])
{
    cout << "------------------main thread start------------------" << endl;
    if (argc < 3)
    {
        cout << "invalid parameters!" << endl;
        cout << "2 parameters are need:" << endl
            << "param 1: ip;" << endl
            << "param 2: port." << endl;
        return 0;
    }
    string addr;
    int port;
    if (argv[1] != nullptr)
    {
        char tmp[256] = "\0";
        unicode2Ansi(argv[1], tmp);
        addr = tmp;
    }
    if (argv[2] != nullptr)
    {
        char tmp[256] = "\0";
        unicode2Ansi(argv[2], tmp);
        port = atoi(tmp);
    }
    cout << "init..." << endl;
    WSADATA wsaData;
    int rst = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (rst != NO_ERROR)
    {
        cout << "WSAStartup failed with:" << rst << endl;
        return 0;
    }
    g_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (g_sock == INVALID_SOCKET)
    {
        cout << "create socket failed with:" << WSAGetLastError() << endl;
        goto goexit;
    }
    cout << "init success." << endl
        << "bind " << addr << ":" << port << "..." << endl;
    sockaddr_in sockin;
    sockin.sin_family = AF_INET;
    sockin.sin_port = htons(port);
    if (addr.compare("any") == 0)
        sockin.sin_addr.S_un.S_addr = INADDR_ANY;
    else
        inet_pton(AF_INET, addr.c_str(), &sockin.sin_addr);
    if (bind(g_sock, (SOCKADDR *)&sockin, sizeof(sockin)) == SOCKET_ERROR)
    {
        cout << "bind failed with:" << WSAGetLastError() << endl;
        closesocket(g_sock);
        goto goexit;
    }
    cout << "bind success." << endl
        << "listen..." << endl;
    if (listen(g_sock, 10) == SOCKET_ERROR)
    {
        cout << "listen failed with:" << WSAGetLastError() << endl;
        closesocket(g_sock);
        goto goexit;
    }
    unsigned long nblock = 1;
    if (ioctlsocket(g_sock, FIONBIO, &nblock) == SOCKET_ERROR)
    {
        cout << "ioctlsocket failed with:" << WSAGetLastError() << endl;
        closesocket(g_sock);
        goto goexit;
    }
    HANDLE hThreads[2] = { NULL };
    hThreads[0] = (HANDLE)_beginthreadex(NULL, 0, listenProc, NULL, 0, NULL);
    if (hThreads[0] == NULL)
    {
        cout << "start listen thread failed with:" << GetLastError() << endl;
        closesocket(g_sock);
        goto goexit;
    }
    hThreads[1] = (HANDLE)_beginthreadex(NULL, 0, requestProc, NULL, 0, NULL);
    if (hThreads[1] == NULL)
    {
        cout << "start request thread failed with:" << GetLastError() << endl;
        closesocket(g_sock);
        goto goexit;
    }
    while (true)
    {
        if (_kbhit())
        {
            if (getchar() == 'q')
            {
                g_bContinue = false;
                cout << "recv exit event,now exit!" << endl;
                for (int i = 0; i < g_totalCnt; i++)
                    closesocket(g_clients[i].sock);
                closesocket(g_sock);
                break;
            }
        }
        Sleep(500);
    }
    if (WaitForMultipleObjects(2, hThreads, TRUE, INFINITE) == WAIT_OBJECT_0)
        cout << "all thread had exit" << endl;
goexit:
    WSACleanup();
    cout << "------------------main thread exit------------------" << endl;
    //system("pause");
    return 0;
}

unsigned int __stdcall listenProc(void *param)
{
    cout << "------listen thread start------" << endl;
    sockaddr_in addr;
    int addrlen = sizeof(addr);
    while (g_bContinue)
    {
        //cout << "listen..." << endl;
        SOCKET sock = accept(g_sock, (SOCKADDR *)&addr, &addrlen);
        if (sock != SOCKET_ERROR)
        {
            g_clients[g_totalCnt].sock = sock;
            inet_ntop(AF_INET, &addr.sin_addr, g_clients[g_totalCnt].addr, 64);
            g_clients[g_totalCnt].port = ntohs(addr.sin_port);
            cout << "a new client come:" << g_clients[g_totalCnt].addr << ":" << g_clients[g_totalCnt].port << ",total:" << ++g_totalCnt << endl;
        }
        else
        {
            int rst = WSAGetLastError();
            if (rst == WSAEWOULDBLOCK)
                continue;
            cout << "accept failed with:" << rst << endl;
            break;
        }
        Sleep(50);
    }
    cout << "------listen thread exit------" << endl;
    return 0;
}
unsigned int __stdcall requestProc(void *param)
{
    cout << "------request thread start------" << endl;
    fd_set readset;
    timeval tval = { 1, 0 };
    while (g_bContinue)
    {
        //cout << "waiting request..." << endl;
        FD_ZERO(&readset);
        for (int i = 0; i < g_totalCnt; i++)
            FD_SET(g_clients[i].sock, &readset);
        int rst = select(0, &readset, NULL, NULL, &tval);
        if (rst == 0)
            continue;
        if (rst > 0)
        {
            for (int i = 0; i < g_totalCnt; i++)
            {
                if (FD_ISSET(g_clients[i].sock, &readset))
                {
                    char buffer[1024] = "\0";
                    rst = recv(g_clients[i].sock, buffer, 1024, 0);
                    if (rst > 0)
                    {
                        cout << "msg from " << g_clients[i].addr << ":" << g_clients[i].port << ":" << buffer << endl;
                        char msg[256] = "recv your msg!";
                        send(g_clients[i].sock, msg, 256, 0);
                        continue;
                    }
                    if (rst == 0 || (rst == SOCKET_ERROR &&WSAGetLastError() == WSAECONNRESET))
                    {
                        closesocket(g_clients[i].sock);
                        cout << g_clients[i].addr << ":" << g_clients[i].port << " quit,total:" << g_totalCnt - 1 << endl;
                        for (int j = i; j < g_totalCnt - 1; j++)
                            g_clients[j] = g_clients[j + 1];
                        g_totalCnt--;
                    }
                }
            }
        }
        Sleep(1000);
    }
    cout << "------request thread exit------" << endl;
    return 0;
}
void unicode2Ansi(const wchar_t *wsBuffer, char *szBuffer, int *nMultyLen)
{
    int len = WideCharToMultiByte(CP_ACP, 0, wsBuffer, -1, NULL, 0, NULL, NULL);
    char *pbuffer = new char[len + 1];
    memset(pbuffer, 0x00, len + 1);
    if (WideCharToMultiByte(CP_ACP, 0, wsBuffer, -1, pbuffer, len, NULL, NULL) > 0)
    {
        memset(szBuffer, 0x00, len + 1);
        memcpy(szBuffer, pbuffer, len);
        if (nMultyLen != NULL)
            *nMultyLen = len;
    }
    delete[] pbuffer;
}

client:

#include "stdafx.h"
#include <WinSock2.h>
#include <ws2tcpip.h>
#include <iostream>
#include <conio.h>

using namespace std;
#pragma comment(lib,"ws2_32.lib")

void unicode2Ansi(const wchar_t *wsBuffer, char *szBuffer, int *nMultyLen = NULL);

int _tmain(int argc, _TCHAR* argv[])
{
    if (argc < 3)
    {
        cout << "invalid parameters!" << endl;
        cout << "2 parameters are need:" << endl
            << "param 1: server ip;" << endl
            << "param 2: server port." << endl;
        return 0;
    }
    char szServer[64] = "\0";
    int port = 0;
    if (argv[1] != NULL)
        unicode2Ansi(argv[1], szServer);
    if (argv[2] != NULL)
    {
        char tmp[64] = "\0";
        unicode2Ansi(argv[2], tmp);
        port = atoi(tmp);
    }

    cout << "init..." << endl;
    WSADATA wsaData;
    int rst = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (rst != NO_ERROR)
    {
        cout << "WSAStartup failed with:" << rst << endl;
        return 0;
    }
    SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (sock == INVALID_SOCKET)
    {
        cout << "create socket failed with:" << WSAGetLastError() << endl;
        goto goexit;
    }
    cout << "init success." << endl;

    cout << "connect " << szServer << ":" << port << "..." << endl;
    sockaddr_in addrin;
    addrin.sin_family = AF_INET;
    inet_pton(AF_INET, szServer, &addrin.sin_addr);
    addrin.sin_port = htons(port);
    rst = connect(sock, (SOCKADDR *)&addrin, sizeof(addrin));
    if (rst == SOCKET_ERROR)
    {
        cout << "connect failed with:" << WSAGetLastError() << endl;
        closesocket(sock);
        goto goexit;
    }
    cout << "connect success." << endl;

    while (true)
    {
        cout << "input message(q for exit):";
        char msg[1024] = "\0";
        cin.getline(msg, 1024);
        if (strcmp(msg, "q") == 0)
            break;
        rst = send(sock, msg, 1024, 0);
        if (rst == SOCKET_ERROR)
        {
            cout << "send msg failed with:" << WSAGetLastError() << endl;
            break;
        }
        memset(msg, 0x00, sizeof(msg));
        rst = recv(sock, msg, 1024, 0);
        if (rst > 0)
        {
            cout << "recv msg:" << msg << endl;
            continue;
        }
        if (rst == 0 || (rst == SOCKET_ERROR &&WSAGetLastError() == WSAECONNRESET))
        {
            cout << "lose connect!" << endl;
            break;
        }
    }
    closesocket(sock);
goexit:
    WSACleanup();
    cout << "exit" << endl;
    //system("pause");
    return 0;
}

void unicode2Ansi(const wchar_t *wsBuffer, char *szBuffer, int *nMultyLen)
{
    int len = WideCharToMultiByte(CP_ACP, 0, wsBuffer, -1, NULL, 0, NULL, NULL);
    char *pbuffer = new char[len + 1];
    memset(pbuffer, 0x00, len + 1);
    if (WideCharToMultiByte(CP_ACP, 0, wsBuffer, -1, pbuffer, len, NULL, NULL) > 0)
    {
        memset(szBuffer, 0x00, len + 1);
        memcpy(szBuffer, pbuffer, len);
        if (nMultyLen != NULL)
            *nMultyLen = len;
    }
    delete[] pbuffer;
}

 

posted on 2018-10-18 15:35  bigpotato  阅读(208)  评论(0)    收藏  举报