TCP流式套接字与I/O复用Select模型代码

来源:互联网 发布:windows snmp工具 编辑:程序博客网 时间:2024/06/05 20:27

C++的socket编程:实现了Server和Client端的通信,主要功能:

Server获取Client的system的时间,Server和Client互相收发文件



Server端代码:

#include "stdafx.h"#undef UNICODE #define WIN32_LEAN_AND_MEAN #include<windows.h> #include<winsock2.h> #include<iostream>#include<ctime>#include<time.h>#include<ws2tcpip.h> #include<stdlib.h> #include<stdio.h> #include<cstdio>#include<cstring>using namespace std;#pragma comment (lib, "Ws2_32.lib") #define DEFAULT_BUFLEN 1024#define DEFAULT_PORT 30000#define DEFAULT_DATA "Hello, I' m Mr.Trojan."#define cmdline1 "GetTime"#define cmdline2 "SendData"#define cmdline3 "RecvData"int main(int argc, _TCHAR* argv[]){    WSADATA wsaData;    int iResult; SOCKET ServerSocket = INVALID_SOCKET, AcceptSocket = INVALID_SOCKET;     char recvbuf[DEFAULT_BUFLEN];     int recvbuflen = DEFAULT_BUFLEN; sockaddr_in addrClient;int addrClientlen = sizeof(sockaddr_in);    //Winsock初始化    iResult = WSAStartup(MAKEWORD(2,2), &wsaData);     if (iResult != 0) { printf("WSAStartup failed: %d\n", iResult);     return -1;    } // 创建监听套接字    ServerSocket = socket(AF_INET,SOCK_STREAM, IPPROTO_IP);           if(ServerSocket == INVALID_SOCKET) {        printf("socket failed: %ld\n", WSAGetLastError());         WSACleanup();        return -1;    }     // 绑定地址和端口号SOCKADDR_IN addrServ;       addrServ.sin_family = AF_INET;       addrServ.sin_port = htons(DEFAULT_PORT);    addrServ.sin_addr.S_un.S_addr = htonl(INADDR_ANY);        iResult = bind(ServerSocket,(const struct sockaddr*)&addrServ,sizeof(SOCKADDR_IN));     if (iResult == SOCKET_ERROR) {        printf("bind failed: %d\n", WSAGetLastError());         closesocket(ServerSocket);         WSACleanup();         return -1;    }     // 监听     iResult = listen(ServerSocket, SOMAXCONN);       if(iResult == SOCKET_ERROR)   {           printf("listen failed !\n");           closesocket(ServerSocket);           WSACleanup();           return -1;       }// 开启TCP连接printf("TCP server starting\n");fd_set fdRead,fdSocket;    FD_ZERO( &fdSocket );FD_SET( ServerSocket, &fdSocket);while(1){//通过select等待数据到达事件    fdRead = fdSocket;iResult = select( 0, &fdRead, NULL, NULL, NULL);if (iResult >0){//有网络事件发生//确定有哪些套接字有未决的I/O,并进一步处理这些I/Ofor (int i=0; i<(int)fdSocket.fd_count; i++){if (FD_ISSET( fdSocket.fd_array[i] ,&fdRead)){if( fdSocket.fd_array[i] == ServerSocket){if( fdSocket.fd_count < FD_SETSIZE){//同时复用的套接字数量最大为FD_SETSIZEAcceptSocket = accept(ServerSocket,(sockaddr FAR*)&addrClient,&addrClientlen);   if( AcceptSocket == INVALID_SOCKET){   printf("accept failed !\n");closesocket(ServerSocket);WSACleanup();   return -1;}//复用等待FD_SET( AcceptSocket, &fdSocket);cout<<"Accept a new trojan:";printf("%s", inet_ntoa(addrClient.sin_addr));cout << "  post:  " << addrClient.sin_port << endl;}else{printf("连接个数超限!\n"); continue;}}else{//数据memset(recvbuf,0,recvbuflen);iResult = recv( fdSocket.fd_array[i], recvbuf, recvbuflen, 0); if (iResult > 0) {     //情况1:成功接收到数据//printf("\nBytes received: %d\n", iResult); cout<<recvbuf<<endl;if (strcmp(recvbuf, DEFAULT_DATA)==0){//将本地时间发送给客户端char choose[DEFAULT_BUFLEN];printf("-----------------------\n");printf("-------1:GetTime-------\n");printf("-------2:SendData------\n");printf("-------3:RecvData------\n");printf("-------q:Nothing-------\n");printf("-----------------------\n");scanf_s("%s",choose);if (strlen(choose)==1){if (choose[0] == '1'){send(AcceptSocket, cmdline1, strlen(cmdline1), 0);int err = recv(AcceptSocket, recvbuf, DEFAULT_BUFLEN, 0);if (err > 0){recvbuf[err] = '\0';cout << recvbuf << endl;}}else if (choose[0] == '2'){send(AcceptSocket, cmdline2, strlen(cmdline2), 0);scanf_s("%s",recvbuf);int err = send(AcceptSocket,recvbuf,sizeof(recvbuf),0);if (err > 0){cout << "发送成功" << endl;}else{cout << "发送失败" << endl;}}else if (choose[0] == '3'){send(AcceptSocket, cmdline3, strlen(cmdline3), 0);int err = recv(AcceptSocket, recvbuf, DEFAULT_BUFLEN, 0);if (err > 0){recvbuf[err] = '\0';cout << recvbuf << endl;}}else if (choose[0] == 'q'){//Do nothing}else{puts("input error");}}}} else if (iResult == 0) {//情况2:连接关闭printf("The trojan is dead.\n\n"); closesocket(fdSocket.fd_array[i]);FD_CLR(fdSocket.fd_array[i], &fdSocket);}else { //情况3:接收失败printf("recv failed with error: %d\n",WSAGetLastError() ); closesocket(fdSocket.fd_array[i]); FD_CLR(fdSocket.fd_array[i], &fdSocket);} }}}}else{printf("select failed with error: %d\n",WSAGetLastError() ); return -1;}}    // 关闭    closesocket(ServerSocket);     WSACleanup();     return 0; }

Client端代码:

#include"stdafx.h"#include<stdio.h>  #include<winsock2.h>  #include<wincrypt.h>#include<time.h>#include<cstring>#include<iostream>  #include<string.h> #pragma comment(lib, "ws2_32.lib")   #pragma comment(lib, "crypt32.lib")#pragma comment(lib, "user32.lib")#pragma comment(lib, "shlwapi.lib")using namespace std;#define DEFAULT_IP "127.0.0.1"#define DEFAULT_PORT 30000#define DEFAULT_BUFLEN 1024#define DEFAULT_DATA "Hello, I' m Mr.Trojan."#define cmdline1 "GetTime"#define cmdline2 "SendData"#define cmdline3 "RecvData"int Hello(SOCKET S){SOCKET clientSocket = S;int err;err = send(clientSocket, DEFAULT_DATA, sizeof(DEFAULT_DATA), 0);if (err > 0){return 0;}return 1;}int main(){int ConnectTimes = 20;while(ConnectTimes--){WORD sockVersion = MAKEWORD(2, 2);WSADATA wsaData;int error = WSAStartup(sockVersion, &wsaData);if (error == -1){cout << "fail to startup" << GetLastError() << endl;WSACleanup();return -1;}SOCKET socketClient = socket(AF_INET, SOCK_STREAM, 0);if (socketClient == INVALID_SOCKET){cout << "socket error!  " << GetLastError() << endl;WSACleanup();closesocket(socketClient);return -1;}sockaddr_in addrServer;addrServer.sin_addr.S_un.S_addr = inet_addr(DEFAULT_IP);addrServer.sin_family = AF_INET;addrServer.sin_port = htons(DEFAULT_PORT);connect(socketClient, (SOCKADDR*)&addrServer, sizeof(SOCKADDR));Hello(socketClient);char recvbuf[DEFAULT_BUFLEN];memset(recvbuf, 0, sizeof(recvbuf));recv(socketClient,recvbuf, DEFAULT_BUFLEN, 0);if (strcmp(recvbuf,cmdline1)==0){time_t t = time(0);char currenttime[DEFAULT_BUFLEN];strftime(currenttime, sizeof(currenttime), "%Y/%m/%d %X", localtime(&t));printf_s("my currenttime is:%s\n",currenttime);error = send(socketClient,currenttime,sizeof(currenttime),0);if (error > 0){cout << "发送成功" << endl;}else{cout << "发送失败" << endl;}}else if(strcmp(recvbuf,cmdline2)==0){error = recv(socketClient,recvbuf, DEFAULT_BUFLEN, 0);if (error > 0){recvbuf[error] = '\0';puts(recvbuf);}}else if(strcmp(recvbuf,cmdline3)==0){puts("input data:");gets_s(recvbuf);error = send(socketClient,recvbuf,sizeof(recvbuf),0);if (error > 0){cout << "发送成功" << endl;}else{cout << "发送失败" << endl;}}else{//Nothing}closesocket(socketClient);if (ConnectTimes % 2){Sleep(300);}else{Sleep(2000);}}return 0;}


原创粉丝点击