赞
踩
#ifndef _TCPSOCKET_H_ #define _TCPSOCKET_H #include<WinSock2.h> // windows平台网络库头文件 #include<WS2tcpip.h> #pragma comment(lib, "ws2_32.lib") // 库文件 #include<stdbool.h> #include<stdio.h> // 服务器端口 #define PORT 8899 // [0, 65536) // 封装错误提示 #define err(errMsg) printf("[line:%d] %s failed code %d\n", __LINE__, errMsg, WSAGetLastError()); // 初始化socket bool init_Socket(); // 关闭socket bool close_Socket(); // 发送消息 bool sendMsg(int fd, const char* msg); // 接收消息 bool recvMsg(int fd, char* buf, int bufSize); #endif // !_TCPSOCKET_H_
#include "tcpSocket.h" bool init_Socket() { WSADATA wsadata; if (0 != WSAStartup(MAKEWORD(2, 2), &wsadata)) { err("WSAStartup"); return false; } return true; } bool close_Socket() { if (0 != WSACleanup()) { err("WSACleanup"); return false; } return true; } // 发送消息 bool sendMsg(int fd, const char* msg) { int ret = send(fd, msg, strlen(msg) + 1, 0); if (ret == -1) { err("send msg"); return false; } return true; } // 接收消息 bool recvMsg(int fd, char* buf, int bufSize) { //printf("buf:%d\n", sizeof(buf)); // 这里的大小为指针的大小 int len = recv(fd, buf, bufSize, 0); if (len > 0) { printf("服务端说: %s\n", buf); return true; } else if (len == 0) { printf("服务器端已经断开了...\n"); } else { perror("recv"); } return false; }
#include "../tcpSocket/tcpSocket.h" #include <thread> // 客户端信息结构体 struct SockInfo { sockaddr_in addr; int fd; }; // 客户端工作函数 void* working(SockInfo *pinfo); // 客户端数组 SockInfo infos[512] = { 0 }; int main() { // 初始化网络库 init_Socket(); // 1. 创建空 socket // param1: 地址协议族 ipv4 ipv6 // param2: 传输协议类型 流式套接字 数据报 // param3: 使用具体的某个传输协议 SOCKET fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (fd == -1) { err("socket"); return -1; } // 2. 给socket绑定ip地址和端口号 sockaddr_in saddr; saddr.sin_family = AF_INET; saddr.sin_port = htons(PORT); saddr.sin_addr.S_un.S_addr = INADDR_ANY; int ret = bind(fd, (sockaddr*)&saddr, sizeof(saddr)); if (ret == -1) { err("bind"); return -1; } //3. 监听 ret = listen(fd, 10); if (ret == -1) { err("listen"); return -1; } printf("等待客户端连接...\n"); // 初始化存客户端的数组 int max = sizeof(infos) / sizeof(infos[0]); for (int i = 0; i < max; ++i) { infos[i].fd = -1; } //4. 如果有客户端请求连接 int addrLen = sizeof(sockaddr_in); while (1) { // 为新客户端连接准备存储位置 SockInfo* pinfo = nullptr; for (int i = 0; i < max; ++i) { if (infos[i].fd == -1) { pinfo = &infos[i]; break; } } // 挂起,等待新连接,有新连接则运行 int cfd = accept(fd, (struct sockaddr*)&pinfo->addr, &addrLen); if (cfd == -1) { err("accept"); break; } pinfo->fd = cfd; // 有客户端连接,启动工作线程 std::thread Worker(working, pinfo); Worker.detach(); } closesocket(fd); close_Socket(); return 0; } /* * 打印客户端信息,接收和发送客户端消息 */ void* working(SockInfo *pinfo) { //SockInfo* pinfo = (SockInfo*)arg; // 连接成功,打印客户端的IP和端口 char ip[32]; printf("客户端fd: %d, IP:%s, 端口:%d\n", pinfo->fd, inet_ntop(AF_INET, &pinfo->addr.sin_addr.S_un, ip, sizeof(ip)), ntohs(pinfo->addr.sin_port) ); //5. 可以和客户端进行通信 // 从指定的socket接受消息 while (1) { char buf[1024]; // 接收消息 if (recvMsg(pinfo->fd, buf, sizeof(buf))) { sendMsg(pinfo->fd, buf); } } int ret = closesocket(pinfo->fd); if (ret == 0) { printf("释放客户端fd:%d\n", pinfo->fd); } pinfo->fd = -1; return NULL; }
#include <iostream> #include "../tcpSocket/tcpSocket.h" int main() { init_Socket(); // 1. 创建空 socket // param1: 地址协议族 ipv4 ipv6 // param2: 传输协议类型 流式套接字 数据报 // param3: 使用具体的某个传输协议 SOCKET fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (fd == -1) { err("socket"); return -1; } // 2. 与服务器建立连接 struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_port = htons(PORT); inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.S_un.S_addr); int ret = connect(fd, (sockaddr*)&addr, sizeof(addr)); if ( ret == -1) { err("connect"); return -1; } int number = 0; while (1) { // 给服务器发送消息 sendMsg(fd, "你好,我是客户端"); // 接收服务器消息 char recvBuf[BUFSIZ]; memset(recvBuf, 0, sizeof(recvBuf)); if (!recvMsg(fd, recvBuf, sizeof(recvBuf))){ break; } printf("接收到的消息:%s\n", recvBuf); Sleep(1000); } closesocket(fd); close_Socket(); return 0; }
#ifndef _TCPSOCKET_H_ #define _TCPSOCKET_H_ #include <iostream> #include <thread> #include <map> #include <WinSock2.h> #include <WS2tcpip.h> #pragma comment(lib, "ws2_32.lib") // 服务器端口 #define PORT 8899 // [0, 65536) class TcpSocket { public: TcpSocket(); ~TcpSocket(); public: // public share bool InitSocket(); bool CloseSocket(); void CreateSocket(); bool RecvMsg(int fd, char* buf, int bufSize); bool SendMsg(int fd, const char* msg); // server bool BindSocket(); bool ListenSocket(int clientNumber); bool AcceptConnect(); void* ServerWorking(int cfd); // client bool ConnectServerSocket(); void* ClientWorking(); void ShowError(const char* msg); public: int m_fd; private: std::map<int, sockaddr_in*> m_pClientSockInfo; }; #endif // !__TCPSOCKET_H_
#include "TcpSocket.h" bool TcpSocket::InitSocket() { WSADATA wsadata; if (0 != WSAStartup(MAKEWORD(2, 2), &wsadata)) { ShowError("WSAStartup"); return false; } return true; } bool TcpSocket::CloseSocket() { if (0 != WSACleanup()) { ShowError("WSACleanup"); return false; } return true; } void TcpSocket::CreateSocket() { SOCKET fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (fd == -1) { ShowError("socket create"); } m_fd = fd; } // 接收消息 bool TcpSocket::RecvMsg(int fd, char* buf, int bufSize) { //printf("buf:%d\n", sizeof(buf)); // 这里的大小为指针的大小 int len = recv(fd, buf, bufSize, 0); if (len > 0) { return true; } else if (len == 0) { printf("fd:%d, 链接已经断开了...\n", fd); } else { perror("recv"); } return false; } bool TcpSocket::SendMsg(int fd, const char* msg) { if (-1 == send(fd, msg, strlen(msg) + 1, 0)) { ShowError("send"); return false; } return true; } // 给socket绑定ip地址和端口号 bool TcpSocket::BindSocket() { sockaddr_in saddr; saddr.sin_family = AF_INET; saddr.sin_port = htons(PORT); saddr.sin_addr.S_un.S_addr = INADDR_ANY; if (-1 == bind(m_fd, (sockaddr*)&saddr, sizeof(saddr))) { ShowError("bind"); return false; } return true; } // 监听 bool TcpSocket::ListenSocket(int clientNumber) { if (-1 == listen(m_fd, clientNumber)) { ShowError("listen"); return false; } return true; } //4. 如果有客户端请求连接 bool TcpSocket::AcceptConnect() { int addrLen = sizeof(sockaddr_in); while (1) { printf("等待客户端连接...\n"); sockaddr_in* outAddr = new sockaddr_in; int cfd = accept(m_fd, (struct sockaddr*)outAddr, &addrLen); if (cfd == -1) { ShowError("accept"); return false; } m_pClientSockInfo.insert(std::pair<int, sockaddr_in*>(cfd, outAddr)); // 连接成功,打印客户端的IP和端口 char ip[32]; printf("客户端fd: %d, IP:%s, 端口:%d\n", cfd, inet_ntop(AF_INET, &m_pClientSockInfo.at(cfd)->sin_addr.S_un, ip, sizeof(ip)), ntohs(m_pClientSockInfo.at(cfd)->sin_port) ); printf("客户端数量:%d\n", m_pClientSockInfo.size()); // 有客户端连接,先和客户端打个招呼,在启动工作线程 SendMsg(cfd, "Welcome to ctp auto trade\n"); std::thread Worker(&TcpSocket::ServerWorking, this, cfd); Worker.detach(); } return true; } void* TcpSocket::ServerWorking(int cfd) { printf("Server Message: client cfd:%d connected\n", cfd); // 从指定的socket接受消息 while (1) { char buf[1024]; // 接收消息 if (RecvMsg(cfd, buf, sizeof(buf)) ) { SendMsg(cfd, buf); } else { // 退出循环 break; } } if (closesocket(cfd) == 0) { //删除容器中值为key的元素。 m_pClientSockInfo.erase(cfd); printf("释放客户端fd:%d\n", cfd); } return nullptr; } // Client与服务器建立连接 bool TcpSocket::ConnectServerSocket() { struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_port = htons(PORT); inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.S_un.S_addr); if (-1 == connect(m_fd, (sockaddr*)&addr, sizeof(addr))) { ShowError("connect"); return false; } // 客户端工作线程 std::thread ClientWork(&TcpSocket::ClientWorking, this); ClientWork.detach(); return true; } void* TcpSocket::ClientWorking() { printf("Client Working\n"); while (1) { char buf[512]; if (RecvMsg(m_fd, buf, sizeof(buf))) { printf("Client Recv: %s\n", buf); } else { printf("Client Recv: 服务端已经关闭\n"); break; } } return nullptr; } void TcpSocket::ShowError(const char* msg) { printf("[line:%d] %s failed code %d\n", __LINE__, msg, WSAGetLastError()); } TcpSocket::TcpSocket() { InitSocket(); } TcpSocket::~TcpSocket() { CloseSocket(); }
#include <iostream>
#include "../tcpSocket/TcpSocket.h"
int main()
{
TcpSocket tcpSocket;
tcpSocket.CreateSocket();
tcpSocket.BindSocket();
tcpSocket.ListenSocket(100);
tcpSocket.AcceptConnect();
system("pause");
return 0;
}
#include <iostream>
#include "../tcpSocket/TcpSocket.h"
int main()
{
TcpSocket tcpSocket;
tcpSocket.CreateSocket();
tcpSocket.ConnectServerSocket();
system("pause");
return 0;
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。