C/S编程
阅读原文时间:2023年07月11日阅读:5

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

WSADATA wsa;
int main(int argc, char **argv) {
WSAStartup(MAKEWORD(, ), &wsa);
SOCKET ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(ListenSocket == INVALID_SOCKET) {
printf("TCP listen socket error %d!\n", WSAGetLastError());
}
char hostname[];
gethostname(hostname, sizeof(hostname));
hostent *pHostent = gethostbyname(hostname);
SOCKADDR_IN ListenAddr;
ListenAddr.sin_family = AF_INET;
ListenAddr.sin_port = htons((USHORT)atoi(argv[]));
for(DWORD i = ; pHostent -> h_addr_list[i]; i++) {
printf ("IP address %lu:%s\n", 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!\n", WSAGetLastError());
}
if(listen(ListenSocket, SOMAXCONN) == SOCKET_ERROR) {
printf("TCP listen error %d!\n", 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!\n", WSAGetLastError());
}
TcpClientCount++;
if(TcpClientCount >= MAX_CLIENT) {
printf("> MAX_CLIENT\n");
closesocket(TcpSocket);
continue;
}
TcpThreadParam Param;
Param.sock = TcpSocket;
Param.addr = TcpClientAddr;
DWORD dwTcpThreadId;
thread tcpt(TCPFun, &Param, dwTcpThreadId);
tcpt.detach();
}
closesocket(ListenSocket);
WSACleanup();
return ;
}

客户端:

#include
#include
#include
#include
#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[] = "GET CUR TIME";
USHORT ServerUDPPort;
bool islogin = false;
char user[];
char password[];
char realUser[];
void sendMessage(SOCKET s) {
while(true) {
memset(content, , sizeof(content));
memset(TCPSendBuf, , sizeof(TCPSendBuf));
scanf("%s", content);
// printf("%s\n", content);
if(strcmp(content, "exit") != ) {
// printf("%s\n", realUser);
sprintf(TCPSendBuf, "%s:%s", realUser, content);
if(send(s, TCPSendBuf, strlen(TCPSendBuf), ) == SOCKET_ERROR) {
printf("send Message error %d\n", WSAGetLastError());
}
}
else {
if(send(s, content, strlen(content), ) == SOCKET_ERROR) {
printf("send Message error %d\n", WSAGetLastError());
}
return;
}
}
}

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

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章