开启辅助访问 切换到宽版

精易论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

用微信号发送消息登录论坛

新人指南 邀请好友注册 - 我关注人的新帖 教你赚取精币 - 每日签到


求职/招聘- 论坛接单- 开发者大厅

论坛版规 总版规 - 建议/投诉 - 应聘版主 - 精华帖总集 积分说明 - 禁言标准 - 有奖举报

查看: 1180|回复: 20
收起左侧

[易语言纯源码] ETCP C++代码 整理 WinSocket

[复制链接]
头像被屏蔽
结帖率:100% (4/4)
发表于 2024-6-29 23:02:14 | 显示全部楼层 |阅读模式   安徽省合肥市
分享源码
界面截图: -
是否带模块: -
备注说明: -
本帖最后由 盖伦总管 于 2024-6-29 23:04 编辑

学习下C++ 对代码进行了整理
下次分片 整理一下每个功能 以及用提 把自己的理解科普分享下
mingw32 控制台直接编译
g++ -shared -o WinSocket.dll WinSocket.cpp WinSocket.def -lws2_32

#include <SDKDDKVer.h>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <WinSock2.h>

#pragma comment(lib,"WS2_32.lib")
#pragma comment(lib,"msvcrt.lib")
#include <stdio.h>
#include <mswsock.h>
#include <MSTcpIP.h>
#include <process.h>

#define tcp_server_connt        1
#define tcp_server_recv                2
#define tcp_server_stop                3
#define tcp_server_send                4
#define tcp_server_close        5

#define tcp_client_connt        1
#define tcp_client_recv                2
#define tcp_client_send                4
#define tcp_client_close        5

#define tcp_len                                65535

typedef void(__stdcall *onServer_ex)(HANDLE Server, SOCKET so, int type, char *buf, int len, int count);
typedef void(__stdcall *onClient_ex)(HANDLE Client, SOCKET so, int type, char *buf, int len);

extern int g_cpu;
extern int buf_len;

extern HANDLE hEvent_Server;
extern HANDLE hEvent_Client;

extern onServer_ex onServerFunc;
extern onClient_ex onClientFunc;

HANDLE hEvent_Server = NULL;
HANDLE hEvent_Client = NULL;
int g_cpu = 0;
int buf_len = 512;
onServer_ex onServerFunc = NULL;
onClient_ex onClientFunc = NULL;

int closesockets(SOCKET so);
int closesockets(SOCKET so) {
        if (INVALID_SOCKET == so) {
                return 0;
        }
        struct linger lingerStruct;
        lingerStruct.l_onoff = 1;
        lingerStruct.l_linger = 0;
        setsockopt(so, SOL_SOCKET, SO_LINGER, (char *)&lingerStruct, sizeof(lingerStruct));
        shutdown(so, SD_BOTH);
        return closesocket(so);
}
bool __stdcall socket_local(char* ip) {
        char hostname[256];
        int ret = gethostname(hostname, sizeof(hostname));
        if (ret == SOCKET_ERROR) {
                return false;
        }
        HOSTENT* host = gethostbyname(hostname);
        if (host == NULL) {
                return false;
        }
        strcpy(ip, inet_ntoa(*(in_addr*)*host->h_addr_list));
        return true;
}

class Socket_Server_IO;
typedef struct server_struct {
        OVERLAPPED        op;
        Socket_Server_IO                        *so;
        int                        state;
        SOCKET                c_so;
        char                *buf;
        DWORD                slen;
        DWORD                cb;
        DWORD                bufSize;
        DWORD                bufOffset;
} S_server_struct, *P_server_struct;
class Socket_Server_IO {
public:
        Socket_Server_IO(void);
        ~Socket_Server_IO(void);
public:
        int Init(char * host, unsigned short nPort, int nIsSC);
        int AcceptServer();
        int Accept();
        void ClientAccept(bool error, P_server_struct op);
        void RecvData(bool error, P_server_struct op);
        int Close();
        int doSend(SOCKET so, char* buf, DWORD cb);
        int doSend_sync(SOCKET so, char* buf, DWORD cb);
        void OnSend(bool ercode, P_server_struct op);
        char* get_ip(SOCKET so) {
                sockaddr_in in;
                int len = sizeof(in);
                getpeername(so, (sockaddr*)&in, &len);
                return inet_ntoa(in.sin_addr);
        }
        SOCKET get_socket() {
                return m_so;
        }
        u_short get_port() {
                sockaddr_in in;
                int len = sizeof(in);
                getsockname(m_so, (sockaddr*)&in, &len);
                return ntohs(in.sin_port);
        }
        char* get_addr(SOCKET m_so) {
                sockaddr_in in;
                int len = sizeof(in);
                getsockname(m_so, (sockaddr*)&in, &len);
                return inet_ntoa(in.sin_addr);
        }
public:
        SOCKET m_so;
        int        m_cnum;
        CRITICAL_SECTION m_cs;
        BOOL m_Is;
        BOOL m_Close;
};

Socket_Server_IO::Socket_Server_IO(void) {
        m_Close = FALSE;
        InitializeCriticalSection(&m_cs);
        m_cnum = 0;
        m_so = INVALID_SOCKET;
}
Socket_Server_IO::~Socket_Server_IO(void) {
        m_cnum = 0;
        m_so = INVALID_SOCKET;
}
int Socket_Server_IO::Init(char * host, unsigned short nPort, int nIs) {
        m_Is = nIs;
        m_so = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, 0, 0, WSA_FLAG_OVERLAPPED);
        if (INVALID_SOCKET == m_so) {
                printf("Init->WSASocket \n");
                return WSAGetLastError();
        }
        HANDLE t = CreateIoCompletionPort((HANDLE)m_so, hEvent_Server, 0, 0);
        if (NULL == t) {
                Close();
                printf("Init->CreateIoCompletionPort \n");
                return GetLastError();
        }
        sockaddr_in in;
        in.sin_family = AF_INET;
        in.sin_addr.S_un.S_addr = inet_addr(host);
        in.sin_port = htons(nPort);
        if (SOCKET_ERROR == bind(m_so, (SOCKADDR *)&in, sizeof (in))) {
                printf("Init->bind \n");
                Close();
                return WSAGetLastError();
        }
        if (SOCKET_ERROR == listen(m_so, g_cpu)) {
                Close();

                return WSAGetLastError();
        }
        return AcceptServer();
}
int Socket_Server_IO::AcceptServer() {
        server_struct *op = new server_struct;
        memset(op, 0, sizeof(server_struct));
        op->buf = new char[buf_len];
        op->so = this;
        op->bufSize = buf_len;
        op->bufOffset = 0;
        op->state = tcp_server_connt;
        op->c_so = INVALID_SOCKET;
        op->c_so = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, 0, 0, WSA_FLAG_OVERLAPPED);
        if (INVALID_SOCKET == op->c_so) {
                delete[]op->buf;
                op->buf = NULL;
                delete[]op;
                op = NULL;
                Close();
                return WSAGetLastError();
        }
        //必须设置
        setsockopt(op->c_so, SOL_SOCKET, SO_RCVBUF, (const char*)&buf_len, sizeof(int));
        int nSendBuf = 0;
        setsockopt(op->c_so, SOL_SOCKET, SO_SNDBUF, (const char*)&nSendBuf, sizeof(int));
        BOOL bReuseaddr = TRUE;
        setsockopt(op->c_so, SOL_SOCKET, SO_REUSEADDR, (const char*)&bReuseaddr, sizeof(BOOL));
        HANDLE t = NULL;
        t = CreateIoCompletionPort((HANDLE)op->c_so, hEvent_Server, 0, 0);
        if (NULL == t) {
                closesockets(op->c_so);
                op->c_so = INVALID_SOCKET;

                delete[]op->buf;
                op->buf = NULL;

                delete[]op;
                op = NULL;
                Close();
                return GetLastError();
        }
        LPFN_ACCEPTEX        lpfnAcceptEx = NULL;
        GUID lGUID = WSAID_ACCEPTEX;
        DWORD cb = 0;
        if (WSAIoctl(m_so, SIO_GET_EXTENSION_FUNCTION_POINTER, &lGUID, sizeof(GUID), &lpfnAcceptEx, sizeof(lpfnAcceptEx), &cb, NULL, NULL)) {
                closesockets(op->c_so);
                op->c_so = INVALID_SOCKET;

                delete[]op->buf;
                op->buf = NULL;

                delete[]op;
                op = NULL;
                Close();
                return 2;
        }
        DWORD Cb = 0;
        if (lpfnAcceptEx(m_so, op->c_so, op->buf, 0, sizeof(sockaddr) + 16, sizeof(sockaddr) + 16, &Cb, (LPOVERLAPPED)op)) {
                closesockets(op->c_so);
                op->c_so = INVALID_SOCKET;

                delete[]op->buf;
                op->buf = NULL;
                delete[]op;
                op = NULL;
                Close();
                return 3;
        }
        return 0;
}
int Socket_Server_IO::Close() {
        m_Close = TRUE;
        m_cnum = 0;
        closesockets(m_so);

        m_so = INVALID_SOCKET;
        return 0;
}
int Socket_Server_IO::Accept() {
        server_struct *op = new server_struct;
        memset(op, 0, sizeof(server_struct));
        op->buf = new char[buf_len];
        op->so = this;
        op->bufSize = buf_len;
        op->bufOffset = 0;
        op->state = tcp_server_connt;
        op->c_so = INVALID_SOCKET;
        op->c_so = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, 0, 0, WSA_FLAG_OVERLAPPED);
        if (INVALID_SOCKET == op->c_so) {
                delete[]op->buf;
                op->buf = NULL;

                delete[]op;
                op = NULL;
                return WSAGetLastError();
        }
        //必须设置
        setsockopt(op->c_so, SOL_SOCKET, SO_RCVBUF, (const char*)&buf_len, sizeof(int));
        int nSendBuf = 0;
        setsockopt(op->c_so, SOL_SOCKET, SO_SNDBUF, (const char*)&nSendBuf, sizeof(int));
        BOOL bReuseaddr = TRUE;
        setsockopt(op->c_so, SOL_SOCKET, SO_REUSEADDR, (const char*)&bReuseaddr, sizeof(BOOL));

        HANDLE t = NULL;
        t = CreateIoCompletionPort((HANDLE)op->c_so, hEvent_Server, 0, 0);
        if (NULL == t) {
                closesockets(op->c_so);
                op->c_so = INVALID_SOCKET;
                PostQueuedCompletionStatus(hEvent_Server, 0, 0, (LPOVERLAPPED)op);
                delete[]op->buf;
                op->buf = NULL;
                delete[]op;
                op = NULL;
                return GetLastError();
        }
        LPFN_ACCEPTEX        lpfnAcceptEx = NULL;
        GUID lGUID = WSAID_ACCEPTEX;
        DWORD cb = 0;
        if (WSAIoctl(m_so, SIO_GET_EXTENSION_FUNCTION_POINTER, &lGUID, sizeof(GUID), &lpfnAcceptEx, sizeof(lpfnAcceptEx), &cb, NULL, NULL)) {
                closesockets(op->c_so);
                op->c_so = INVALID_SOCKET;
                PostQueuedCompletionStatus(hEvent_Server, 0, 0, (LPOVERLAPPED)op);

                delete[]op->buf;
                op->buf = NULL;

                delete[]op;
                op = NULL;
                return 2;
        }
        DWORD Cb = 0;
        if (lpfnAcceptEx(m_so, op->c_so, op->buf, 0, sizeof(sockaddr) + 16, sizeof(sockaddr) + 16, &Cb, (LPOVERLAPPED)op)) {
                closesockets(op->c_so);
                op->c_so = INVALID_SOCKET;
                PostQueuedCompletionStatus(hEvent_Server, 0, 0, (LPOVERLAPPED)op);

                delete[]op->buf;
                op->buf = NULL;

                delete[]op;
                op = NULL;
                return 3;
        }
        return 0;
}

void Socket_Server_IO::ClientAccept(bool error, P_server_struct nop) {
        while (0 != Accept()) {
                Sleep(1);
        }
        setsockopt(nop->c_so, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, (char*)&m_so, sizeof(SOCKET));
        DWORD Cb = 0;
        tcp_keepalive ka;
        ka.onoff = 1;
        ka.keepalivetime = 1000 * 30;
        ka.keepaliveinterval = 1000 * 5;
        WSAIoctl(nop->c_so, SIO_KEEPALIVE_VALS, &ka, sizeof(ka), NULL, 0, &Cb, NULL, NULL);
        EnterCriticalSection(&m_cs);
        m_cnum++;
        LeaveCriticalSection(&m_cs);
        onServerFunc(this, nop->c_so, tcp_server_connt, NULL, 0, m_cnum);
        //如果该客户端进入就断开了
        if (error) {
                EnterCriticalSection(&m_cs);
                m_cnum--;
                LeaveCriticalSection(&m_cs);
                onServerFunc(this, nop->c_so, tcp_server_close, NULL, 0, m_cnum);
                closesockets(nop->c_so);
                nop->c_so = INVALID_SOCKET;
                delete[]nop->buf;
                nop->buf = NULL;
                delete nop;
                nop = NULL;
                return;
        }
        nop->state = tcp_server_recv;
        WSABUF wsabuf;
        if (m_Is) {
                delete []nop->buf;
                nop->bufOffset = 0;
                nop->buf = new char[sizeof(DWORD)];
                nop->bufSize = sizeof(DWORD);
                wsabuf.buf = nop->buf + nop->bufOffset;
                wsabuf.len = nop->bufSize - nop->bufOffset;
        } else {
                wsabuf.buf = nop->buf;
                wsabuf.len = buf_len;
        }
        DWORD Flg = 0;
        Cb = 0;
        if (WSARecv(nop->c_so, &wsabuf, 1, &Cb, &Flg, (LPWSAOVERLAPPED)nop, NULL)) {
                int ercode = WSAGetLastError();
                if (ercode == WSAEFAULT) {
                        return;
                } else if (ercode != WSA_IO_PENDING) {
                        EnterCriticalSection(&m_cs);
                        m_cnum--;
                        LeaveCriticalSection(&m_cs);
                        onServerFunc(this, nop->c_so, tcp_server_close, NULL, 0, m_cnum);
                        closesockets(nop->c_so);
                        nop->c_so = INVALID_SOCKET;
                        delete[]nop->buf;
                        nop->buf = NULL;
                        delete nop;
                        nop = NULL;
                        return;
                }
        }
}
void Socket_Server_IO::RecvData(bool error, P_server_struct nop) {
        if (error) {
                EnterCriticalSection(&m_cs);
                m_cnum--;
                LeaveCriticalSection(&m_cs);
                onServerFunc(this, nop->c_so, tcp_server_close, 0, 0, m_cnum);
                //closesockets(nop->c_so);
                //nop->c_so = INVALID_SOCKET;
                delete[]nop->buf;
                nop->buf = NULL;
                delete nop;
                nop = NULL;
                return;
        }
        if (m_Is) {
                nop->bufOffset += nop->cb;
                if (nop->bufOffset < nop->bufSize) {
                        nop->state = tcp_server_recv;
                        WSABUF wsabuf;
                        if (m_Is) {
                                wsabuf.buf = nop->buf + nop->bufOffset;
                                wsabuf.len = nop->bufSize - nop->bufOffset;
                        } else {
                                wsabuf.buf = nop->buf;
                                wsabuf.len = buf_len;
                        }
                        DWORD Cb = 0;
                        DWORD Flg = 0;
                        if (WSARecv(nop->c_so, &wsabuf, 1, &Cb, &Flg, (LPWSAOVERLAPPED)nop, NULL)) {
                                int ercode = WSAGetLastError();
                                if (ercode == WSAEFAULT) {
                                        return;
                                } else if (ercode != WSA_IO_PENDING) {
                                        EnterCriticalSection(&m_cs);
                                        m_cnum--;
                                        LeaveCriticalSection(&m_cs);

                                        onServerFunc(this, nop->c_so, tcp_server_close, 0, 0, m_cnum);

                                        delete[]nop->buf;
                                        nop->buf = NULL;

                                        delete nop;
                                        nop = NULL;
                                        return;
                                }
                        }
                        return;
                }
                DWORD size = *((DWORD*)(nop->buf));
                if (size > 65536000) {
                        EnterCriticalSection(&m_cs);
                        m_cnum--;
                        LeaveCriticalSection(&m_cs);
                        onServerFunc(this, nop->c_so, tcp_server_close, 0, 0, m_cnum);
                        //closesockets(nop->c_so);
                        //nop->c_so = INVALID_SOCKET;
                        delete[]nop->buf;
                        nop->buf = NULL;
                        delete nop;
                        nop = NULL;
                        return;
                }
                if (nop->bufOffset < DWORD(sizeof(DWORD)) + size) { //完整性检测
                        delete[] nop->buf;

                        nop->buf = new char[sizeof(DWORD) + size];
                        nop->bufSize = sizeof(DWORD) + size;
                        nop->bufOffset = sizeof(DWORD);
                        memcpy(nop->buf, &size, sizeof(DWORD));

                        nop->state = tcp_server_recv;
                        WSABUF wsabuf;
                        if (m_Is) {
                                wsabuf.buf = nop->buf + nop->bufOffset;
                                wsabuf.len = nop->bufSize - nop->bufOffset;
                        } else {
                                wsabuf.buf = nop->buf;
                                wsabuf.len = buf_len;
                        }
                        DWORD Cb = 0;
                        DWORD Flg = 0;
                        if (WSARecv(nop->c_so, &wsabuf, 1, &Cb, &Flg, (LPWSAOVERLAPPED)nop, NULL)) {
                                int ercode = WSAGetLastError();
                                if (ercode == WSAEFAULT) {
                                        return;
                                } else if (ercode != WSA_IO_PENDING) {
                                        EnterCriticalSection(&m_cs);
                                        m_cnum--;
                                        LeaveCriticalSection(&m_cs);

                                        onServerFunc(this, nop->c_so, tcp_server_close, 0, 0, m_cnum);

                                        delete[]nop->buf;
                                        nop->buf = NULL;

                                        delete nop;
                                        nop = NULL;
                                        return;
                                }
                        }
                        return;
                }
                if (nop->bufSize - sizeof(DWORD) > 0) {
                        onServerFunc(this, nop->c_so, tcp_server_recv, nop->buf + sizeof(DWORD), nop->bufSize - sizeof(DWORD), m_cnum);
                }
                delete[]nop->buf;
                nop->buf = new char[sizeof(DWORD)];
                nop->bufSize = sizeof(DWORD);
        } else {
                onServerFunc(this, nop->c_so, tcp_server_recv, nop->buf, nop->cb, m_cnum);
        }

        nop->bufOffset = 0;
        nop->state = tcp_server_recv;
        WSABUF wsabuf;
        if (m_Is) {
                wsabuf.buf = nop->buf + nop->bufOffset;
                wsabuf.len = nop->bufSize - nop->bufOffset;
        } else {
                wsabuf.buf = nop->buf;
                wsabuf.len = buf_len;
        }
        DWORD Cb = 0;
        DWORD Flg = 0;
        if (WSARecv(nop->c_so, &wsabuf, 1, &Cb, &Flg, (LPWSAOVERLAPPED)nop, NULL)) {
                int ercode = WSAGetLastError();
                if (ercode == WSAEFAULT) {
                        return;
                } else if (ercode != WSA_IO_PENDING) {
                        EnterCriticalSection(&m_cs);
                        m_cnum--;
                        LeaveCriticalSection(&m_cs);
                        onServerFunc(this, nop->c_so, tcp_server_close, 0, 0, m_cnum);
                        //closesocket(nop->c_so);
                        //nop->c_so = INVALID_SOCKET;
                        //PostQueuedCompletionStatus(hEvent_Server, 0, NULL, (LPOVERLAPPED)nop);
                        delete[]nop->buf;
                        nop->buf = NULL;
                        delete nop;
                        nop = NULL;
                }
        }
}
int Socket_Server_IO::doSend(SOCKET so, char* buf, DWORD cb) {
        if (cb > 65536000) {
                return 0;
        }
        server_struct *op = new server_struct;
        memset(op, 0, sizeof(server_struct));
        op->so = this;
        op->state = tcp_server_send;
        WSABUF wsabuf;
        if (m_Is) {
                op->buf = new char[sizeof(DWORD) + cb];
                op->bufSize = sizeof(DWORD) + cb;
                wsabuf.buf = op->buf;
                wsabuf.len = op->bufSize;
                memcpy(wsabuf.buf, &cb, sizeof(DWORD));
                memcpy(wsabuf.buf + sizeof(DWORD), buf, cb);
        } else {
                wsabuf.buf = buf;
                wsabuf.len = cb;
        }
        op->bufOffset = 0;
        if (WSASend(so, &wsabuf, 1, &op->cb, 0, (LPWSAOVERLAPPED)op, NULL)) {
                int ercode = WSAGetLastError();
                if (ercode != WSA_IO_PENDING) {
                        delete[]op->buf;
                        op->buf = NULL;
                        delete op;
                        op = NULL;
                        return 1;
                }
        }
        return 0;
}
int Socket_Server_IO::doSend_sync(SOCKET so, char* buf, DWORD cb) {
        if (cb > 65536000) {
                return 0;
        }
        if (m_Is) {
                memcpy(buf, &cb, sizeof(DWORD));
                memcpy(buf + sizeof(DWORD), buf, cb);
                if (send(so, buf, cb + sizeof(DWORD), 0)) {
                        return 0;
                }
        } else {
                if (send(so, buf, cb, 0)) {
                        return 0;
                }
        }
        return 1;
}
void Socket_Server_IO::OnSend(bool ercode, P_server_struct nop) {
        SOCKET n_so = nop->c_so;
        delete[]nop->buf;
        nop->buf = NULL;
        delete nop;
        nop = NULL;
        if (ercode) {
                closesockets(n_so);
                onServerFunc(this, n_so, tcp_server_stop, 0, 0, m_cnum);
                n_so = INVALID_SOCKET;
        }
}

class Socket_Client_IO;
typedef struct client_struct {
        OVERLAPPED        op;
        Socket_Client_IO        *so;
        int                        state;
        char                *buf;
        DWORD                slen;
        DWORD                cb;
        DWORD                bufSize;
        DWORD                bufOffset;
} S_client_struct, *P_client_struct;

class Socket_Client_IO {
public:
        Socket_Client_IO(void);
        ~Socket_Client_IO(void);
        int Init(char * host, unsigned short nPort, BOOL nIs, int time);
        void OnConnect(bool ercode, P_client_struct op);
        void OnClose(bool ercode, P_client_struct op);
        void OnRecv(bool ercode, P_client_struct op);
        int SoRecv(P_client_struct op);
        int Close();
        int doSend(char* buf, DWORD cb, int isok, char* outbuf, int outtime);
        void OnSend(bool ercode, P_client_struct op);
        SOCKET get_socket() {
                return m_so;
        }
public:
        SOCKET m_so;
        BOOL m_Is;
        int m_isok;
        char* m_buf;
};

Socket_Client_IO::Socket_Client_IO(void) {
        m_so = INVALID_SOCKET;
}
Socket_Client_IO::~Socket_Client_IO(void) {
        m_so = INVALID_SOCKET;
}
extern "C" __declspec(dllexport) int Socket_Client_IO::Init(char * host, unsigned short nPort, BOOL nIs, int time) {
        m_so = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, 0, 0, WSA_FLAG_OVERLAPPED);
        if (INVALID_SOCKET == m_so) {
                return WSAGetLastError();
        }
        HANDLE t = CreateIoCompletionPort((HANDLE)m_so, hEvent_Client, 0, 0);
        if (NULL == t) {
                Close();
                return GetLastError();
        }
        sockaddr_in in;
        in.sin_family = AF_INET;
        in.sin_addr.S_un.S_addr = 0;
        in.sin_port = 0;
        if (SOCKET_ERROR == bind(m_so, (SOCKADDR *)&in, sizeof (in))) {
                Close();
                return WSAGetLastError();
        }
        m_Is = nIs;
        in.sin_family = AF_INET;
        struct hostent *pHost;
        pHost = gethostbyname(host);
        memcpy(&in.sin_addr.S_un.S_addr, pHost->h_addr_list[0], pHost->h_length);
        in.sin_addr.S_un.S_addr = inet_addr(inet_ntoa(in.sin_addr));
        in.sin_port = htons(nPort);
        unsigned long ul = 1;
        ioctlsocket(m_so, FIONBIO, (unsigned long *)&ul);
        connect(m_so, (sockaddr*)&in, sizeof(sockaddr));
        struct timeval timeout ;
        fd_set r;
        FD_ZERO(&r);
        FD_SET(m_so, &r);
        timeout.tv_sec = time;
        timeout.tv_usec = 0;
        int ret = select(m_so, 0, &r, 0, &timeout);
        if ( ret <= 0 ) {
                Close();
                return 1;
        }
        client_struct *op = new client_struct;
        memset(op, 0, sizeof(client_struct));
        op->so = this;
        op->state = tcp_client_connt;
        op->buf = NULL;
        op->bufSize = 0;
        op->bufOffset = 0;
        PostQueuedCompletionStatus(hEvent_Client, 0, 0, (LPOVERLAPPED)op);
        return 0;
}
extern "C" __declspec(dllexport) void Socket_Client_IO::OnConnect(bool ercode, P_client_struct op) {
        setsockopt(m_so, SOL_SOCKET, 0x7010, NULL, 0);
        onClientFunc(this, m_so, 1, NULL, 0);
        if (ercode) {
                OnClose(ercode, op);
                return;
        }
        delete[]op->buf;
        if (m_Is) {
                op->buf = new char[sizeof(DWORD)];
                op->bufSize = sizeof(DWORD);
        } else {
                op->buf = new char[tcp_len];
                op->bufSize = tcp_len;
        }
        op->state = tcp_client_recv;
        op->bufOffset = 0;
        if (1 == SoRecv(op)) {
                OnClose(ercode, op);
                return;
        }
}
void Socket_Client_IO::OnRecv(bool ercode, P_client_struct op) {
        if (ercode) {
                OnClose(ercode, op);
                return;
        }
        if (m_Is) {
                op->bufOffset += op->cb; //更新大小

                if (op->bufOffset < op->bufSize) { //完整性检测
                        if (1 == SoRecv(op)) {
                                OnClose(ercode, op);
                                return ;
                        }
                        return;
                }

                DWORD size = *((DWORD*)(op->buf));

                if (size > 65536000) { //数据错误
                        OnClose(ercode, op);
                        return;
                }

                if (op->bufOffset < DWORD(sizeof(DWORD)) + size) { //完整性检测
                        delete[] op->buf;
                        op->buf = new char[sizeof(DWORD) + size];
                        op->bufSize = sizeof(DWORD) + size;
                        op->bufOffset = sizeof(DWORD);
                        memcpy(op->buf, &size, sizeof(DWORD));
                        if (1 == SoRecv(op)) {
                                OnClose(ercode, op);
                                return;
                        }
                        return;
                }
                if (op->bufSize - sizeof(DWORD) > 0) {
                        if (m_isok > 0) {
                                memcpy(m_buf, op->buf + sizeof(DWORD), op->bufSize - sizeof(DWORD));
                                m_isok = 0;
                        }
                        onClientFunc(this, m_so, 2, op->buf + sizeof(DWORD), op->bufSize - sizeof(DWORD));
                }
                delete[] op->buf;
                op->buf = new char[sizeof(DWORD)];
                op->bufSize = sizeof(DWORD);
        } else {
                if (m_isok > 0) {
                        memcpy(m_buf, op->buf, op->cb);
                }
                onClientFunc(this, m_so, 2, op->buf, op->cb);
                m_isok = 0;
        }
        op->bufOffset = 0;
        if (1 == SoRecv(op)) {
                OnClose(ercode, op);
                return;
        }
}
int Socket_Client_IO::SoRecv(P_client_struct op) {
        op->so = this;
        op->state = tcp_client_recv;
        WSABUF wsabuf;
        wsabuf.buf = op->buf + op->bufOffset;
        wsabuf.len = op->bufSize - op->bufOffset;
        DWORD Flg = 0;
        if (WSARecv(m_so, &wsabuf, 1, &op->cb, &Flg, (LPWSAOVERLAPPED)op, NULL)) {
                int ercode = WSAGetLastError();
                if (ercode == WSAEFAULT) {
                        return 0;
                } else if (ercode != WSA_IO_PENDING) {
                        return 1;
                }
        }
        return 0;
}
void Socket_Client_IO::OnClose(bool ercode, P_client_struct op) {
        delete[]op->buf;
        op->buf = NULL;
        delete op;
        op = NULL;
        onClientFunc(this, m_so, 3, NULL, 0);
        Close();
}
int Socket_Client_IO::Close() {
        closesockets(m_so);
        m_so = INVALID_SOCKET;
        return 0;
}
int Socket_Client_IO::doSend(char* buf, DWORD cb, int isok, char* outbuf, int outtime) {
        if (cb > 65536000) {
                return 0;
        }
        m_isok = isok;
        m_buf = outbuf;
        client_struct *op = new client_struct;
        memset(op, 0, sizeof(client_struct));
        op->so = this;
        op->state = tcp_client_send;
        WSABUF wsabuf;
        if (m_Is) {
                op->buf = new char[sizeof(DWORD) + cb];
                op->bufSize = sizeof(DWORD) + cb;
                wsabuf.buf = op->buf;
                wsabuf.len = op->bufSize;
                memcpy(wsabuf.buf, &cb, sizeof(DWORD));
                memcpy(wsabuf.buf + sizeof(DWORD), buf, cb);
        } else {
                op->buf = buf;
                op->bufSize = cb;
                wsabuf.buf = op->buf;
                wsabuf.len = op->bufSize;
        }
        if (WSASend(m_so, &wsabuf, 1, &op->cb, 0, (LPWSAOVERLAPPED)op, NULL)) {
                int ercode = WSAGetLastError();
                if (ercode != WSA_IO_PENDING) {
                        delete[]op->buf;
                        delete op;
                        return 1;
                }
        }
        int ni = 0;
        if (outtime <= 0) {
                outtime = 2;
        }
        outtime = outtime * 1000;
        while (1 == m_isok) {
                ni++;
                if (ni > outtime) {
                        m_isok = 0;
                        m_buf = NULL;
                        break;
                }
                Sleep(1);
        }
        return 0;
}

void Socket_Client_IO::OnSend(bool ercode, P_client_struct op) {
        if (ercode) {
                OnClose(ercode, op);
                return;
        }
        if (m_Is) {
                delete[]op->buf;
                delete op;
        }
}

unsigned __stdcall Worker_server(void* pParam) {
        while (true) {
                ULONG cb = 0;
                ULONG_PTR key = 0;
                server_struct* op = nullptr;
                bool error = false;

                if (!GetQueuedCompletionStatus(hEvent_Server, &cb, &key, (LPOVERLAPPED * )&op, INFINITE)) {
                        error = true;
                }

                Socket_Server_IO* so = op->so;
                if (op->state == tcp_server_recv && cb <= 0) {
                        error = true;
                }

                op->cb = cb;

                if (so->m_Close) {
                        so->OnSend(true, op);
                        continue;
                }

                switch (op->state) {
                case tcp_server_connt:
                        so->ClientAccept(error, op);
                        break;
                case tcp_server_recv:
                        so->RecvData(error, op);
                        break;
                case tcp_server_send:
                        so->OnSend(error, op);
                        break;
                default:
                        // Handle unexpected state
                        break;
                }
        }

        _endthreadex(0);
        return 0;
}

// Client worker function
unsigned __stdcall Worker_client(void* pParam) {
        while (true) {
                ULONG cb = 0;
                ULONG_PTR key = 0;
                client_struct* op = nullptr;
                bool error = false;

                if (!GetQueuedCompletionStatus(hEvent_Client, &cb, &key, (LPOVERLAPPED * )&op, INFINITE)) {
                        error = true;
                }

                Socket_Client_IO* so = op->so;
                if (op->state == tcp_client_recv && cb <= 0) {
                        error = true;
                }

                op->cb = cb;

                switch (op->state) {
                case tcp_client_connt:
                        so->OnConnect(error, op);
                        break;
                case tcp_client_recv:
                        so->OnRecv(error, op);
                        break;
                case tcp_client_send:
                        so->OnSend(error, op);
                        break;
                default:
                        // Handle unexpected state
                        break;
                }
        }

        _endthreadex(0);
        return 0;
}

extern "C" __declspec(dllexport) int __stdcall socket_init(onServer_ex nFun, onClient_ex cFun) {
        WSAData wsa;
        if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0) {
                return WSAGetLastError();
        }

        onServerFunc = nFun;
        onClientFunc = cFun;

        hEvent_Server = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
        if (hEvent_Server == NULL) {
                return GetLastError();
        }

        hEvent_Client = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
        if (hEvent_Client == NULL) {
                CloseHandle(hEvent_Server);
                return GetLastError();
        }

        SYSTEM_INFO info;
        GetSystemInfo(&info);
        g_cpu = info.dwNumberOfProcessors + 2;
        if (g_cpu < 5) {
                g_cpu = 5;
        }

        for (int i = 0; i < g_cpu; i++) {
                HANDLE threadHandle = (HANDLE)_beginthreadex(NULL, 0, &Worker_server, NULL, 0, NULL);
                if (threadHandle != NULL) {
                        CloseHandle(threadHandle);
                }

                threadHandle = (HANDLE)_beginthreadex(NULL, 0, &Worker_client, NULL, 0, NULL);
                if (threadHandle != NULL) {
                        CloseHandle(threadHandle);
                }
        }

        return 0;
}

extern "C" __declspec(dllexport) int __stdcall socket_server(char * host, unsigned short nPort, int nIs) {
        Socket_Server_IO * dServer = new Socket_Server_IO;
        if (0 != dServer->Init(host, nPort, nIs)) {
                delete dServer;
                dServer = NULL;
                return 0;
        }
        return 0;
        //return (int)dServer;
}
extern "C" __declspec(dllexport) int __stdcall socket_server_send(HANDLE sso, SOCKET so, char *buf, int len) {
        return ((Socket_Server_IO*)sso)->doSend(so, buf, len);
}
extern "C" __declspec(dllexport) int __stdcall socket_server_sends(HANDLE sso, SOCKET so, char *buf, int len) {
        return ((Socket_Server_IO*)sso)->doSend_sync(so, buf, len);
}
extern "C" __declspec(dllexport) int __stdcall socket_server_get_port(HANDLE so) {
        return ((Socket_Server_IO*)so)->get_port();
}
char* __stdcall socket_server_get_ip(HANDLE so, SOCKET client_so) {
        return ((Socket_Server_IO*)so)->get_ip(client_so);
}
SOCKET __stdcall socket_server_get_socket(HANDLE so) {
        return ((Socket_Server_IO*)so)->get_socket();
}
extern "C" __declspec(dllexport) int __stdcall socket_server_close(SOCKET so) {
        return closesockets(so);
}

extern "C" __declspec(dllexport) int __stdcall socket_server_stop(HANDLE so) {
        if (IsBadReadPtr (so, 4) != 0) {
                return 0;
        }
        Socket_Server_IO* dServer = ((Socket_Server_IO*)so);
        dServer->Close();
        delete dServer;
        dServer = NULL;
        return 0;
}

extern "C" __declspec(dllexport) int __stdcall socket_client(char * host, unsigned short nPort, BOOL nIs, int time) {
        Socket_Client_IO * dClient = new Socket_Client_IO;
        if (0 != dClient->Init(host, nPort, nIs, time)) {
                delete dClient;
                dClient = NULL;
                return 0;
        }
        return 0;
        //return (int)dClient;
}
extern "C" __declspec(dllexport) int __stdcall socket_client_send(HANDLE so, char *buf, int len, int isok, char* outbuf, int outtime) {
        return ((Socket_Client_IO*)so)->doSend(buf, len, isok, outbuf, outtime);
}

extern "C" __declspec(dllexport) int __stdcall socket_client_close(HANDLE so) {
        return ((Socket_Client_IO*)so)->Close();
}

extern "C" __declspec(dllexport) int __stdcall socket_client_get(HANDLE so) {
        return ((Socket_Client_IO*)so)->get_socket();
}

//
//// Example implementation of the callback functions
//void __stdcall ServerCallback(HANDLE Server, SOCKET so, int type, char *buf, int len, int count) {
//        //printf("ServerCallback invoked with type: %d, len: %d, count: %d\n", type, len, count);
//        
//        // 打印接收到的数据
//        printf("Received data: ");
//        for (int i = 0; i < len; ++i) {
//                printf("%c", buf[i]);
//        }
//        printf("\n");
//        if(type==1){
//                char sendData[] = "ServerCallback:helloworld";
//                socket_server_send(Server, so, sendData, strlen(sendData));
//        }
//        
//}
//
//
//void __stdcall ClientCallback(HANDLE Client, SOCKET so, int type, char *buf, int len) {
//        //("ClientCallback invoked with type: %d, len: %d\n", type, len);
//        
//        // 打印接收到的数据
//        printf("Received data: ");
//        for (int i = 0; i < len; ++i) {
//                printf("%c", buf[i]);
//        }
//        printf("\n");
//        if(type==1){
//                char sendData[] = "ClientCallback:helloworld";
//                socket_client_send(Client, sendData, strlen(sendData), 0, 0, 0);
//        }
//        
//}
//
//int __stdcall main() {
//        if (socket_init(ServerCallback, ClientCallback) == 0) {
//                char hostname[] = "192.168.10.2";
//                Socket_Server_IO * s = new Socket_Server_IO;
//                printf("S %d \n", s->Init(hostname, 8800, 0));
//                Socket_Client_IO * c = new Socket_Client_IO;
//                printf("C %d \n", c->Init(hostname, 8800, 0, 30));
//                Sleep(1000 * 60 * 60 * 30);
//        }
//        return 0;
//}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved) {
        switch (ul_reason_for_call) {
        case DLL_PROCESS_ATTACH:
        case DLL_THREAD_ATTACH:
        case DLL_THREAD_DETACH:
        case DLL_PROCESS_DETACH:
                break;
        }
        return TRUE;
}

WinSocket.rar

232.28 KB, 下载次数: 13, 下载积分: 精币 -2 枚

点评

注意 由于是ETCp有一些bug所以易语言模块需要重新封装 之后会增加同步和异步事件处理 所以这算是原始的ETCp移除了客户Duan代理功能   安徽省*  发表于 2024-6-30 04:52

评分

参与人数 3好评 +1 精币 +4 收起 理由
文西哥 + 1 支持开源~!感谢分享
baitso + 1 + 2 感谢分享,很给力!~
財財 + 1 感谢分享,很给力!~

查看全部评分


签到天数: 1 天

发表于 2024-7-7 06:55:37 | 显示全部楼层   重庆市重庆市
支持支持~~~~~
回复 支持 反对

使用道具 举报

结帖率:50% (3/6)

签到天数: 28 天

发表于 2024-7-4 01:27:04 | 显示全部楼层   四川省乐山市
支持支持~~~~~
回复 支持 反对

使用道具 举报

结帖率:50% (3/6)

签到天数: 28 天

发表于 2024-7-4 01:26:52 | 显示全部楼层   四川省乐山市
支持支持~~~~~
回复 支持 反对

使用道具 举报

结帖率:50% (3/6)

签到天数: 28 天

发表于 2024-7-4 01:26:33 | 显示全部楼层   四川省乐山市
支持支持~~~~~
回复 支持 反对

使用道具 举报

签到天数: 2 天

发表于 2024-7-2 14:28:59 | 显示全部楼层   湖北省仙桃市
6666666666666666666666666666
回复 支持 反对

使用道具 举报

结帖率:100% (4/4)

签到天数: 27 天

发表于 2024-7-1 07:59:23 | 显示全部楼层   山东省淄博市
感谢分享
回复 支持 反对

使用道具 举报

结帖率:100% (20/20)

签到天数: 26 天

发表于 2024-6-30 15:55:01 | 显示全部楼层   江苏省泰州市
感谢大佬无私分享
回复 支持 反对

使用道具 举报

结帖率:80% (4/5)

签到天数: 2 天

发表于 2024-6-30 09:38:54 | 显示全部楼层   山东省潍坊市
已经顶贴,感谢您对论坛的支持!
回复 支持 反对

使用道具 举报

结帖率:0% (0/2)

签到天数: 25 天

发表于 2024-6-30 09:12:53 | 显示全部楼层   广西壮族自治区玉林市
感谢分享,很给力!~
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 致发广告者

发布主题 收藏帖子 返回列表

sitemap| 易语言源码| 易语言教程| 易语言论坛| 易语言模块| 手机版| 广告投放| 精易论坛
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论,本站内容均为会员发表,并不代表精易立场!
论坛帖子内容仅用于技术交流学习和研究的目的,严禁用于非法目的,否则造成一切后果自负!如帖子内容侵害到你的权益,请联系我们!
防范网络诈骗,远离网络犯罪 违法和不良信息举报电话0663-3422125,QQ: 793400750,邮箱:wp@125.la
Powered by Discuz! X3.4 揭阳市揭东区精易科技有限公司 ( 粤ICP备12094385号-1) 粤公网安备 44522102000125 增值电信业务经营许可证 粤B2-20192173

快速回复 返回顶部 返回列表