C/S编程

https://blog.csdn.net/antony1776/article/details/73717666

实现C/S程序,加上登录注册聊天等功能。

然后要做个协议的样子出来。

比如说注册功能要把用户名密码一起发送过去,然后在前面在加一个标志,表示用的是哪个操作。就相当于是一个协议。

然后下面的代码并没有实现协议。

写的很累赘,就是问来问去

struct user {
    int flag;
    string user;
    string password;
    int length;
    char option[MAX_BUF_SIZE];
};

协议一般就是定义一个结构体。

服务器端:

#include<iostream>
#include<map>
#include<Winsock2.h>
#include<thread>
#include<time.h>
#include<cstdio>
#include<vector>
using namespace std;
#define MAX_CLIENT 10
#define MAX_BUF_SIZE 65535
#define UDP_SRV_PORT 2345
typedef pair<SOCKET, string> pii;
int TcpClientCount = 0;
char ServerTCPBuf[MAX_BUF_SIZE];
char ServerUDPBuf[MAX_BUF_SIZE];
char tmp[MAX_BUF_SIZE];
char ServerTCPTimeBuf[256];
//char getTime[256] = "GET CUR TIME";
//typedef pair<bool, string> pbs;
//map<ULONG, pbs> islogin;
struct TcpThreadParam {
    SOCKET sock;
    sockaddr_in addr;
};
vector<pii> onlineUser;
map<string, string> allUser;
map<string, bool> isLogin;
string realUser;
//todo : 聊天
void TCPFun(TcpThreadParam *lpParam, DWORD threadId) {
    SOCKET TcpSocket = ((TcpThreadParam*)lpParam)->sock;
    SOCKADDR_IN TcpClientAddr = ((TcpThreadParam*)lpParam)->addr;
    sprintf(ServerTCPBuf, "%5d%s", UDP_SRV_PORT, "START");
    if(send(TcpSocket, ServerTCPBuf, strlen(ServerTCPBuf), 0) == SOCKET_ERROR) {
        printf("thread %u send start error %d!
", threadId, WSAGetLastError());
    }
    memset(ServerTCPBuf, 0, sizeof(ServerTCPBuf));
    sprintf(ServerTCPBuf, "%s", "1:新用户注册
2:用户登录
3:发消息聊天室
4:得到服务器时间
5:退出请输入exit再重新选择操作
请选择操作");
    if(send(TcpSocket, ServerTCPBuf, strlen(ServerTCPBuf), 0) == SOCKET_ERROR) {
        printf("thread %u send start error %d!
", threadId, WSAGetLastError());
    }
    int TCPBytesReceived;
    time_t CurSysTime;
    struct tm *tblock;
    string user;
    while(true) {
        memset(ServerTCPBuf, 0, sizeof(ServerTCPBuf));
        TCPBytesReceived = recv(TcpSocket, ServerTCPBuf, sizeof(ServerTCPBuf), 0);
        if(TCPBytesReceived == 0 || TCPBytesReceived == SOCKET_ERROR) {
            break;
        }
//        printf("from %d.%d.%d.%d
", TcpClientAddr.sin_addr.S_un.S_un_b.s_b1,
//                TcpClientAddr.sin_addr.S_un.S_un_b.s_b2, TcpClientAddr.sin_addr.S_un.S_un_b.s_b3,
//                TcpClientAddr.sin_addr.S_un.S_un_b.s_b4);
//        ULONG ipULONG = TcpClientAddr.sin_addr.S_un.S_addr;
        int flag;
        flag = (USHORT)atoi(ServerTCPBuf);
        if(flag == 1) {
            memset(ServerTCPBuf, 0, sizeof(ServerTCPBuf));
            sprintf(ServerTCPBuf, "%s", "请输入用户名");
            if(send(TcpSocket, ServerTCPBuf, strlen(ServerTCPBuf), 0) == SOCKET_ERROR) {
                printf("thread %u send user error %d!
", threadId, WSAGetLastError());
            }
            memset(ServerTCPBuf, 0, sizeof(ServerTCPBuf));
            TCPBytesReceived = recv(TcpSocket, ServerTCPBuf, sizeof(ServerTCPBuf), 0);
            user = (string)ServerTCPBuf;
            if(allUser.count(user)) {
                memset(ServerTCPBuf, 0, sizeof(ServerTCPBuf));
                sprintf(ServerTCPBuf, "%s", "该用户名已注册,请输入exit再重新选择操作!");
                if(send(TcpSocket, ServerTCPBuf, strlen(ServerTCPBuf), 0) == SOCKET_ERROR) {
                    printf("thread %u send other user error %d!
", threadId, WSAGetLastError());
                }
            }
            else {
                memset(ServerTCPBuf, 0, sizeof(ServerTCPBuf));
                sprintf(ServerTCPBuf, "%s", "请输入密码");
                if(send(TcpSocket, ServerTCPBuf, strlen(ServerTCPBuf), 0) == SOCKET_ERROR) {
                    printf("thread %u send password error %d!
", threadId, WSAGetLastError());
                }
                memset(ServerTCPBuf, 0, sizeof(ServerTCPBuf));
                TCPBytesReceived = recv(TcpSocket, ServerTCPBuf, sizeof(ServerTCPBuf), 0);
                string password = (string)ServerTCPBuf;
                memset(ServerTCPBuf, 0, sizeof(ServerTCPBuf));
                sprintf(ServerTCPBuf, "%s", "注册成功,请重新选择操作");
                allUser[user] = password;
                if(send(TcpSocket, ServerTCPBuf, strlen(ServerTCPBuf), 0) == SOCKET_ERROR) {
                    printf("thread %u send password error %d!
", threadId, WSAGetLastError());
                }
                allUser[user] = password;
            }
        }
        else if(flag == 2) {
            memset(ServerTCPBuf, 0, sizeof(ServerTCPBuf));
            sprintf(ServerTCPBuf, "%s", "请输入用户名");
            if(send(TcpSocket, ServerTCPBuf, strlen(ServerTCPBuf), 0) == SOCKET_ERROR) {
                printf("thread %u send user error %d!
", threadId, WSAGetLastError());
            }
            memset(ServerTCPBuf, 0, sizeof(ServerTCPBuf));
            TCPBytesReceived = recv(TcpSocket, ServerTCPBuf, sizeof(ServerTCPBuf), 0);
            string user = (string)ServerTCPBuf;
            if(!allUser.count(user)) {
                memset(ServerTCPBuf, 0, sizeof(ServerTCPBuf));
                sprintf(ServerTCPBuf, "%s", "没有该用户,请输入exit再重新选择操作");
                if(send(TcpSocket, ServerTCPBuf, strlen(ServerTCPBuf), 0) == SOCKET_ERROR) {
                    printf("thread %u send no user error %d!
", threadId, WSAGetLastError());
                }
            }
            else {
                memset(ServerTCPBuf, 0, sizeof(ServerTCPBuf));
                sprintf(ServerTCPBuf, "%s", "请输入密码");
                if(send(TcpSocket, ServerTCPBuf, strlen(ServerTCPBuf), 0) == SOCKET_ERROR) {
                    printf("thread %u send password error %d!
", threadId, WSAGetLastError());
                }
                memset(ServerTCPBuf, 0, sizeof(ServerTCPBuf));
                TCPBytesReceived = recv(TcpSocket, ServerTCPBuf, sizeof(ServerTCPBuf), 0);
                string password = (string) ServerTCPBuf;
                if(allUser[user] != password) {
                    memset(ServerTCPBuf, 0, sizeof(ServerTCPBuf));
                    sprintf(ServerTCPBuf, "%s", "exit");
                    if(send(TcpSocket, ServerTCPBuf, strlen(ServerTCPBuf), 0) == SOCKET_ERROR) {
                        printf("thread %u send other password error %d!
", threadId, WSAGetLastError());
                    }
                }
                else {
                    memset(ServerTCPBuf, 0, sizeof(ServerTCPBuf));
                    sprintf(ServerTCPBuf, "%s", "登录成功,请重新选择操作");
                    if(send(TcpSocket, ServerTCPBuf, strlen(ServerTCPBuf), 0) == SOCKET_ERROR) {
                        printf("thread %u send error %d!
", threadId, WSAGetLastError());
                    }
                    isLogin[user] = true;
                    realUser = user;
                    onlineUser.push_back(pii(TcpSocket, user));
                }
            }
        }
        else if(flag == 3) {
            memset(ServerTCPBuf, 0, sizeof(ServerTCPBuf));
            sprintf(ServerTCPBuf, "%s", "请输入内容");
            if(send(TcpSocket, ServerTCPBuf, strlen(ServerTCPBuf), 0) == SOCKET_ERROR) {
                printf("thread %u send content error %d!
", threadId, WSAGetLastError());
            }
            memset(ServerTCPBuf, 0, sizeof(ServerTCPBuf));
            while(true) {
                memset(ServerTCPBuf, 0, sizeof(ServerTCPBuf));
                TCPBytesReceived = recv(TcpSocket, ServerTCPBuf, sizeof(ServerTCPBuf), 0);
                if(strlen(ServerTCPBuf) == 0) break;
                if(strcmp(ServerTCPBuf, "exit") == 0) {
                    send(TcpSocket, ServerTCPBuf, strlen(ServerTCPBuf), 0);
                    isLogin[user] = false;
                    break;
                }
                else {
                    printf("%s
", ServerTCPBuf);
                    for(int i = 0; i < onlineUser.size(); i++) {
                        if(onlineUser[i].first == TcpSocket || !isLogin[onlineUser[i].second]) continue;
                        send(onlineUser[i].first, ServerTCPBuf, strlen(ServerTCPBuf), 0);
                    }
                }
            }
        }
        else {
            CurSysTime = time(NULL);
            tblock = localtime(&CurSysTime);
            memset(ServerTCPBuf, 0, sizeof(ServerTCPBuf));
            strftime(ServerTCPBuf, sizeof(ServerTCPBuf), "%Y-%m-%d %H:%M:%S", tblock);
    //        strcpy(ServerTCPTimeBuf, asctime(tblock));
            memset(ServerTCPTimeBuf, 0, sizeof(ServerTCPTimeBuf));
            sprintf(ServerTCPTimeBuf, "%s
%s", ServerTCPBuf, "请重新选择操作");
            if(send(TcpSocket, ServerTCPTimeBuf, strlen(ServerTCPTimeBuf), 0) == SOCKET_ERROR) {
                printf("thread %u send time error %d!
", threadId, WSAGetLastError());
            }
        }
    }
    closesocket(TcpSocket);
    TcpClientCount--;
}
int ind;
void UDPFun(DWORD threadID) {
    SOCKET UDPSrvSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    char hostname[256];
    gethostname(hostname, sizeof(hostname));
    hostent *pHostent = gethostbyname(hostname);
    SOCKADDR_IN UDPSrvAddr;
    memset(&UDPSrvAddr, 0, sizeof(SOCKADDR_IN));
    UDPSrvAddr.sin_family = AF_INET;
    UDPSrvAddr.sin_port = htons(UDP_SRV_PORT);
    UDPSrvAddr.sin_addr = *(in_addr*)pHostent->h_addr_list[ind];
    bind(UDPSrvSocket, (sockaddr*)&UDPSrvAddr, sizeof(UDPSrvAddr));
    while(true) {
        memset(ServerUDPBuf, 0, sizeof(ServerUDPBuf));
        int iSockAddrLen = sizeof(sockaddr);
        SOCKADDR_IN UDPClientAddr;
        recvfrom(UDPSrvSocket, ServerUDPBuf, sizeof(ServerUDPBuf), 0,
                 (sockaddr*)&UDPClientAddr, &iSockAddrLen);
        iSockAddrLen = sizeof(sockaddr);
        printf("ServerUDPBuf:%s
", ServerUDPBuf);
        sendto(UDPSrvSocket, ServerUDPBuf, strlen(ServerUDPBuf), 0,
               (sockaddr*)&UDPClientAddr, iSockAddrLen);
    }
}

WSADATA wsa;
int main(int argc, char **argv) {
    WSAStartup(MAKEWORD(2, 2), &wsa);
    SOCKET ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if(ListenSocket == INVALID_SOCKET) {
        printf("TCP listen socket error %d!
", WSAGetLastError());
    }
    char hostname[256];
    gethostname(hostname, sizeof(hostname));
    hostent *pHostent = gethostbyname(hostname);
    SOCKADDR_IN ListenAddr;
    ListenAddr.sin_family = AF_INET;
    ListenAddr.sin_port = htons((USHORT)atoi(argv[1]));
    for(DWORD i = 0; pHostent -> h_addr_list[i]; i++) {
        printf ("IP address %lu:%s
", i, inet_ntoa (*(struct in_addr*)pHostent->h_addr_list[i]));
    }
    scanf("%d", &ind);
    ListenAddr.sin_addr = *(in_addr*) pHostent -> h_addr_list[ind];
//    ListenAddr.sin_addr.s_addr = htonl(INADDR_ANY);
    if(bind(ListenSocket, (sockaddr*)&ListenAddr, sizeof(ListenAddr)) == SOCKET_ERROR) {
        printf("TCP bind error %d!
", WSAGetLastError());
    }
    if(listen(ListenSocket, SOMAXCONN) == SOCKET_ERROR) {
        printf("TCP listen error %d!
", WSAGetLastError());
    }
    SOCKET TcpSocket;
    SOCKADDR_IN TcpClientAddr;
    DWORD dwUdpThreadId;
    thread udpt(UDPFun, dwUdpThreadId);
    udpt.detach();
    while(true) {
        int iSockAddrLen = sizeof(sockaddr);
        TcpSocket = accept(ListenSocket, (sockaddr*)&TcpClientAddr, &iSockAddrLen);
        if(TcpSocket == INVALID_SOCKET) {
            printf("TcpSocket error %d!
", WSAGetLastError());
        }
        TcpClientCount++;
        if(TcpClientCount >= MAX_CLIENT) {
            printf("> MAX_CLIENT
");
            closesocket(TcpSocket);
            continue;
        }
        TcpThreadParam Param;
        Param.sock = TcpSocket;
        Param.addr = TcpClientAddr;
        DWORD dwTcpThreadId;
        thread tcpt(TCPFun, &Param, dwTcpThreadId);
        tcpt.detach();
    }
    closesocket(ListenSocket);
    WSACleanup();
    return 0;
}

客户端:

#include <Winsock2.h>
#include <cstdio>
#include <iostream>
#include <thread>
#define MAX_BUF_SIZE 65535 //接收发送缓冲区大小
using namespace std;
char TCPClientBuf[MAX_BUF_SIZE];
char UDPClientBuf[MAX_BUF_SIZE];
char UDPRecvBuf[MAX_BUF_SIZE];
SOCKET TCPSocket, UDPSocket;
char TCPSendBuf[MAX_BUF_SIZE];
char content[MAX_BUF_SIZE];
char getTime[256] = "GET CUR TIME";
USHORT ServerUDPPort;
bool islogin = false;
char user[10];
char password[20];
char realUser[10];
void sendMessage(SOCKET s) {
    while(true) {
        memset(content, 0, sizeof(content));
        memset(TCPSendBuf, 0, sizeof(TCPSendBuf));
        scanf("%s", content);
//        printf("%s
", content);
        if(strcmp(content, "exit") != 0) {
//            printf("%s
", realUser);
            sprintf(TCPSendBuf, "%s:%s", realUser, content);
            if(send(s, TCPSendBuf, strlen(TCPSendBuf), 0) == SOCKET_ERROR) {
                printf("send Message error %d
", WSAGetLastError());
            }
        }
        else {
            if(send(s, content, strlen(content), 0) == SOCKET_ERROR) {
                printf("send Message error %d
", WSAGetLastError());
            }
            return;
        }
    }
}

int main(int argc, char * argv[]) {
    WSADATA wsaData;
    if(WSAStartup(MAKEWORD(2,2),&wsaData)!=0) {
        printf("Failed to load Winsock.
");
        return -1;
    }
    SOCKADDR_IN TCPServer, UDPServer;
    //填写要连接的服务器地址信息
    TCPServer.sin_family = AF_INET;
    TCPServer.sin_port = htons((USHORT)atoi(argv[2]));
    //inet_addr()将命令行中输入的点分IP地址转换为二进制表示的网络字节序IP地址
    TCPServer.sin_addr.s_addr = inet_addr(argv[1]);
    //建立客户端流式套接口
    TCPSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    if(TCPSocket == INVALID_SOCKET) {
        printf("socket() Failed: %d
",WSAGetLastError());
        return -1;
    }
    //请求与服务器端建立TCP连接
    if(connect(TCPSocket,(sockaddr*)&TCPServer,sizeof(TCPServer)) == INVALID_SOCKET) {
        printf("connect() Failed: %d
", WSAGetLastError());
        return -1;
    }
    int BytesReceived;
    BytesReceived = recv(TCPSocket, TCPClientBuf, sizeof(TCPClientBuf), 0);
    if(BytesReceived < 0) {
        printf("UDP port recv error %d!
", WSAGetLastError());
    }
    char portnum[10];
    memcpy(portnum, TCPClientBuf, 5);
    ServerUDPPort = (USHORT)atoi(portnum);
    printf("ServerUDPPort: %d
", ServerUDPPort);
    UDPSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    UDPServer.sin_family = AF_INET;
    UDPServer.sin_port = htons(ServerUDPPort);
    UDPServer.sin_addr.s_addr = inet_addr(argv[1]);
//
    if(strcmp("START", TCPClientBuf + 5) != 0) {
        printf("%s
", TCPClientBuf + 5);
        return -1;
    }
    memset(TCPClientBuf, 0, sizeof(TCPClientBuf));
    BytesReceived = recv(TCPSocket, TCPClientBuf, sizeof(TCPClientBuf), 0);
    printf("%s
", TCPClientBuf);
    int iSockAddrLen;
    while(true) {
        int UserChoice;
//        sudo:输入
        scanf("%d", &UserChoice);
        if(UserChoice > 5) continue;
        memset(TCPSendBuf, 0, sizeof(TCPSendBuf));
        sprintf(TCPSendBuf, "%d", UserChoice);
        if(send(TCPSocket, TCPSendBuf, strlen(TCPSendBuf), 0) == SOCKET_ERROR) {
            printf("choice send error %d
", WSAGetLastError());
        }
        int TCPBytesReceived;
        if(UserChoice == 1) {
            memset(TCPSendBuf, 0, sizeof(TCPSendBuf));
            TCPBytesReceived = recv(TCPSocket, TCPSendBuf, sizeof(TCPSendBuf), 0);
            printf("%s
", TCPSendBuf);
            scanf("%s", user);
            if(send(TCPSocket, user, strlen(user), 0) == SOCKET_ERROR) {
                printf("TCP send user error %d!
", WSAGetLastError());
            }
            memset(TCPSendBuf, 0, sizeof(TCPSendBuf));
            TCPBytesReceived = recv(TCPSocket, TCPSendBuf, sizeof(TCPSendBuf), 0);
            printf("%s
", TCPSendBuf);
            scanf("%s", password);
            if(strcmp(password, "exit") != 0) {
                if(send(TCPSocket, password, strlen(password), 0) == SOCKET_ERROR) {
                    printf("TCP send password error %d!
", WSAGetLastError());
                }
                memset(TCPSendBuf, 0, sizeof(TCPSendBuf));
                TCPBytesReceived = recv(TCPSocket, TCPSendBuf, sizeof(TCPSendBuf), 0);
                printf("%s
", TCPSendBuf);
            }
        }
        else if(UserChoice == 2) {
            memset(TCPSendBuf, 0, sizeof(TCPSendBuf));
            TCPBytesReceived = recv(TCPSocket, TCPSendBuf, sizeof(TCPSendBuf), 0);
            printf("%s
", TCPSendBuf);
            scanf("%s", user);
            if(send(TCPSocket, user, strlen(user), 0) == SOCKET_ERROR) {
                printf("TCP send user error %d!
", WSAGetLastError());
            }
            memset(TCPSendBuf, 0, sizeof(TCPSendBuf));
            TCPBytesReceived = recv(TCPSocket, TCPSendBuf, sizeof(TCPSendBuf), 0);
            printf("%s
", TCPSendBuf);
            scanf("%s", password);
            if(strcmp(password, "exit") != 0) {
                if(send(TCPSocket, password, strlen(password), 0) == SOCKET_ERROR) {
                    printf("TCP send password error %d!
", WSAGetLastError());
                }
                memset(TCPSendBuf, 0, sizeof(TCPSendBuf));
                TCPBytesReceived = recv(TCPSocket, TCPSendBuf, sizeof(TCPSendBuf), 0);
                printf("%s
", TCPSendBuf);
                memset(TCPSendBuf, 0, sizeof(TCPSendBuf));
                if(strcmp(TCPSendBuf, "exit") == 0) {
                    printf("密码错误
");
                }
                else {
                    strncpy(realUser, user, sizeof(user));
                }
//                memset(TCPSendBuf, 0, sizeof(TCPSendBuf));
//                if(send(TCPSocket, TCPSendBuf, strlen(TCPSendBuf), 0) == SOCKET_ERROR) {
//                    printf("TCP send user error %d!
", WSAGetLastError());
//                }
            }
        }
        else if(UserChoice == 3) {
            memset(TCPSendBuf, 0, sizeof(TCPSendBuf));
            TCPBytesReceived = recv(TCPSocket, TCPSendBuf, sizeof(TCPSendBuf), 0);
            printf("%s
", TCPSendBuf);
            thread t(sendMessage, TCPSocket);
            t.detach();
            while(true) {
                memset(TCPSendBuf, 0, sizeof(TCPSendBuf));
                TCPBytesReceived = recv(TCPSocket, TCPSendBuf, sizeof(TCPSendBuf), 0);
                if(strcmp(TCPSendBuf, "exit") == 0) break;
                printf("%s
", TCPSendBuf);
            }
        }
        else if(UserChoice == 4) {
            memset(TCPSendBuf, 0, sizeof(TCPSendBuf));
            TCPBytesReceived = recv(TCPSocket, TCPSendBuf, sizeof(TCPSendBuf), 0);
            printf("%s
", TCPSendBuf);
        }
        else if(UserChoice == 5) {
            closesocket(TCPSocket);
            closesocket(UDPSocket);
            WSACleanup();
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/downrainsun/p/11756156.html