socket C/C++编程(9)windows server端面向对象化处理
来源:互联网 发布:linux调用shell脚本 编辑:程序博客网 时间:2024/05/17 04:15
1. 面向过程的源代码如下,
#include <stdio.h>#include <string.h>#include <thread>#ifdef WIN32 #include <windows.h> #define socklen_t int#else #include <sys/types.h> #include <sys/socket.h> #include <unistd.h> #include <stdlib.h> #include <arpa/inet.h> #define closesocket close //#include <thread>#endifusing namespace std;class TcpThread{ // 多线程类public: void Main(){ // 每一个线程的入口函数 char buf[1024] = {0}; for(;;){ int lenRecv = recv(client,buf, sizeof(buf)-1,0); // server读取client端键入的数据(第二类socket的句柄,存储数据的地方,flag) if(lenRecv <= 0) break; buf[lenRecv] = '\0'; // 客户端键入数据的末尾两位赋值‘、0’ if(strstr(buf,"quit")!= NULL){ break; // 字符串匹配函数,匹配到用户发送了"quit" } printf("Recvd data: %s \n Len: %d \n", buf, lenRecv); // 服务器显示客户端键入的字符串长度 } #ifdef WIN32 // 读取数据的第二类socket创建后要记得关闭 closesocket(client); #else close(client); #endif delete this; // 调用完后,自己清理调第二类socket的对象 } int client;// 每一个客户端的第二类socket};int main(int argc, char *argv[]){ // 初始化”ws2_32.lib” #ifdef WIN32 WSADATA ws; WSAStartup(MAKEWORD(2,2), &ws); #endif // 创建第一类socket int sock = socket(AF_INET,SOCK_STREAM,0); if(sock == -1){ printf("create sock error!\n"); return -1; } // TCP Server指定端口并设置服务端端口的属性,返回(sockaddr*)&saddr unsigned short port = 8080; // 默认端口号 if(argc > 1){ port = atoi(argv[1]); } sockaddr_in saddr; // 声明端口 saddr.sin_family = AF_INET; // TCPIP协议 saddr.sin_port = htons(port); // 绑定端口号, htons()之host-to-network saddr.sin_addr.s_addr = 0; //或htonl(0) 服务器接受的IP地址 0表示接受任意内外网IP // 绑定端口到指定的socket,输入(sockaddr*)&saddr if(::bind(sock, (sockaddr*)&saddr, sizeof(saddr))!=0){ printf("OS bind socks to this port %d failed\n", port); return -2; } printf("OS bind this port %d to sockets successfully!\n", port); listen(sock, 10); // 允许用户连接函数(客户socket(一个客户一个socket),最大请求数队列的长度,) for(;;){ // 支持多个客户端第二类socket sockaddr_in caddr; // 结构体:存储客户端的相关信息:端口号和IP地址s socklen_t len = sizeof(caddr); int client = accept(sock,(sockaddr*)&caddr,&len); // 第二类socket: 创建一个socket专门读取缓冲区clients(这里缓冲区大小如上行listen代码所示为10) if(client<=0)break; printf("accept client %d", client); char *ip = inet_ntoa(caddr.sin_addr); // 客户端IP地址转字符串 unsigned short cport = ntohs(caddr.sin_port);// 客户端端口号(网络字节序转本地字节序) printf("client ip: %s, port is %d\n", ip, cport); // 打印客户端连接信息 TcpThread *th = new TcpThread(); // 创建第二类socket对象 th->client = client; // 传递client到TcpThread对象 thread sth(&TcpThread::Main,th); // 启动线程的入口函数main(),参数为thread,函数库为thread sth() sth.detach(); } closesocket(sock); // 端口的第一类socket,不再交互后也要记得关闭,先二后一时堆栈思想 getchar(); return 0;}
2. 面向对象化之XTcp.h
#pragma once#include <string>class XTcp{public: int sock; unsigned short port; std::string ip; int CreateSocket(); bool Bind(unsigned short port); XTcp Accept(); void Close(); int Recv(char *buf, int bufsize); int Send(const char *buf, int sendsize); XTcp(void); virtual ~XTcp(void);};
3. 面向对象化之XTcp.cpp
#include "XTcp.h"#include <stdio.h>#include <string.h>#include <thread>#ifdef WIN32 #include <windows.h> #define socklen_t int#else #include <sys/types.h> #include <sys/socket.h> #include <unistd.h> #include <stdlib.h> #include <arpa/inet.h> #define closesocket close //#include <thread>#endifusing namespace std;// 创建构造函数XTcp::XTcp(void){ // 初始化”ws2_32.lib”->初始化一次 #ifdef WIN32 static bool first = true; if(first){ first = false; WSADATA ws; WSAStartup(MAKEWORD(2,2), &ws); } #endif}XTcp::~XTcp(void){}// 创建第一类sockint XTcp::CreateSocket(){ // 创建第一类socket sock = socket(AF_INET,SOCK_STREAM,0); if(sock <= 0){ printf("create sock error!\n"); } return sock;}// 绑定端口和listenbool XTcp::Bind(unsigned short port){ if(sock<=0) CreateSocket(); sockaddr_in saddr; // 声明端口 saddr.sin_family = AF_INET; // TCPIP协议 saddr.sin_port = htons(port); // 绑定端口号, htons()之host-to-network saddr.sin_addr.s_addr = 0; //或htonl(0) 服务器接受的IP地址 0表示接受任意内外网IP // 绑定端口到指定的第一类socket,输入(sockaddr*)&saddr if(::bind(sock, (sockaddr*)&saddr, sizeof(saddr))!=0){ printf("OS bind socks to this port %d failed\n", port); return false; } printf("OS bind this port %d to sockets successfully!\n", port); listen(sock, 10); // 允许用户连接函数(客户socket(一个客户一个socket),最大请求数队列的长度,) return true;}//通过tcp socket判断第二类socket是否成功XTcp XTcp::Accept(){ XTcp tcp; // 支持多个客户端第二类socket sockaddr_in caddr; // 结构体:存储客户端的相关信息:端口号和IP地址s socklen_t len = sizeof(caddr); int client = accept(sock,(sockaddr*)&caddr,&len); // 第二类socket: 创建一个socket专门读取缓冲区clients(这里缓冲区大小如上行listen代码所示为10) if(client <= 0) return tcp; printf("accept client %d", client); tcp.ip = inet_ntoa(caddr.sin_addr); // 客户端IP地址转字符串 tcp.port = ntohs(caddr.sin_port);// 客户端端口号(网络字节序转本地字节序) tcp.sock = client; printf("client ip: %s, port is %d\n", tcp.ip.c_str(), tcp.port); // 打印客户端连接信息 return tcp;}void XTcp::Close(){ if(sock <= 0) return; // sock发生错误 closesocket(sock);}int XTcp::Recv(char *buf, int bufsize){ return recv(sock, buf, bufsize, 0);}// 一定要发送完毕int XTcp::Send(const char *buf, int size){ int s = 0; while(s!=size){ int len = send(sock, buf+s, size-s,0); if(len <= 0) break; // 发完退出 s += len; } return s;}
4. 面向对象测试之入口函数 Test.cpp
#include <stdlib.h>#include "XTcp.h"#include <thread>class TcpThread{ // 多线程类public: void Main(){ // 每一个线程的入口函数 char buf[1024] = {0}; for(;;){ int lenRecv = client.Recv(buf, sizeof(buf)-1); // server读取client端键入的数据(第二类socket的句柄,存储数据的地方,flag) if(lenRecv <= 0) break; buf[lenRecv] = '\0'; // 客户端键入数据的末尾两位赋值‘、0’ if(strstr(buf,"quit")!= NULL){ char re[] = "quit success\n"; client.Send(re, strlen(re)+1); break; // 字符串匹配函数,匹配到用户发送了"quit" } int sendlen = client.Send("ok\n",4); printf("Recvd data: %s \n Len: %d \n", buf, lenRecv); // 服务器显示客户端键入的字符串长度 } client.Close(); delete this; // 调用完后,自己清理调第二类socket的对象 } XTcp client;// 每一个客户端的第二类socket};int main(int argc, char *argv[]){ // TCP Server指定端口并设置服务端端口的属性,返回(sockaddr*)&saddr unsigned short port = 9003; // 默认端口号 if(argc > 1){ port = atoi(argv[1]); } XTcp server; //server.CreateSocket(); server.Bind(port); for(;;){ XTcp client = server.Accept(); // 阻塞函数 TcpThread *th = new TcpThread(); // 创建第二类socket对象 th->client = client; // 传递client到TcpThread对象 std::thread sth(&TcpThread::Main,th); // 启动线程的入口函数main(),参数为thread,函数库为thread sth() sth.detach(); } server.Close(); getchar(); return 0;}
客户端并行连接,
服务端创建sockets,接收队列中的clients,
阅读全文
0 0
- socket C/C++编程(9)windows server端面向对象化处理
- socket C/C++编程(10)linux server端面向对象化处理
- socket C/C++编程(8)server端多线程处理clients队列
- Windows C语言 Socket编程 server端(服务器)--初级(简单版)
- TCP Socket编程 C/C 实现 (Windows Platform SDK)
- 用C写windows socket(Server)
- socket C/C++编程(4)Server端向OS请求sockets资源进行server端开放端口号的绑定
- socket C/C++编程(11)windows client端使用ip,port,通过connect()连接上linux server
- TCP Socket编程 C/C++实现 (Windows Platform SDK)
- UDP Socket编程 C/C++实现 (Windows Platform SDK)
- CP Socket编程 C/C++实现 (Windows Platform SDK)
- TCP Socket编程 C/C++实现 (Windows Platform SDK)
- TCP Socket编程 C/C++实现 (Windows Platform SDK)
- UDP Socket编程 C/C++实现 (Windows Platform SDK)
- UDP Socket编程 C/C++实现 (Windows Platform SDK)
- socket C编程设置接收超时(Windows & Linux)
- c在Windows下的socket编程
- socket C/C++编程(3)Windows&Linux之socket兼容性编程
- hbase开发环境搭建及运行hbase小实例(HBase 0.98.3新api)
- 三范式通俗解释
- 软件测试黑马工程师----数据库04(创建表约束)
- 优秀资料
- 使用Handler实现打地鼠(上)
- socket C/C++编程(9)windows server端面向对象化处理
- 学习《笨办法学python》习题11 遇到raw_input输入问题
- selenium+java破解极验滑动验证码
- 20170819周末记账流水(2017-08-19 10:00)
- 下载安装apk 与webview 百度界面
- JAVA运算符
- 结合php与JQuery仅用两个页面对数据库的数据进行增删改
- 设计模式解密(22)- 访问者模式
- keras中文文档笔记10——数据预处理