【tcp-ip学习总结】基于udp的多人聊天室,带有登录注册功能
来源:互联网 发布:淘宝手机详情怎么设置 编辑:程序博客网 时间:2024/05/26 02:19
环境;vs2010,vs2013
服务器端
#include<stdio.h>#include<Winsock2.h>#include<stdlib.h>#pragma comment(lib,"Ws2_32.lib")typedef struct { char username[30];//用户名 char password[50];//用户密码 struct sockaddr_in addr;//用户的地址 int isOnlie;//是否在线}User;SOCKET severSocket;//服务端的socketWSADATA wsaData;struct sockaddr_in serverAddr, clientAddr, showMsgAddr;//服务器端地址,客户端地址,客户端那边消息显示框的地址char recvBuf[1024];//接收缓冲区struct sockaddr_in addrs[10];//客户端地址数组(装有每一个客户端的地址)int count = 0;//地址数组中元素的个数int clientaddrLen;//服务器端的地址长度int recvlen;//接收字符串的长度int i = 0;//循环需要的变量int res;//字符串比较的结果int sendLen;//发送数据的长度char clientIP[1024];//保存当前客户端地址char addrIP[1024];//保存数组中第i个客户端的地址char command;//用户输入的命令User users[100];int userCount;//用户的数量char sendBuf[1024];//发送给客户端的提示字符串char username[30];//登陆人的名字char password[50];//登陆人的密码char *delimiters;//分割的字符串int onlineCount;//显示在线人数char onlineStr[100];//在线人数的字符串格式/*登陆功能*/void login(){ printf("登陆!\n"); //如果接收的整个字符串为a,就提示登陆方法,否则就执行登陆 if (!strcmp("a", recvBuf)) { strcpy(sendBuf, "登陆请在发送框输入(a 用户名 密码)按回车\n"); sendLen = sendto(severSocket, sendBuf, sizeof(sendBuf), 0, (SOCKADDR*)&showMsgAddr, sizeof(showMsgAddr)); if (sendLen == SOCKET_ERROR) { printf("发送失败!"); return; } } else { //分割字符串 delimiters = strtok(recvBuf, " "); delimiters = strtok(NULL, " "); strcpy(username, delimiters);//拿到登陆的username delimiters = strtok(NULL, " "); strcpy(password, delimiters);//拿到登陆的密码 for (i = 0; i < userCount; i++) { if (!strcmp(username, users[i].username)){ if (!strcmp(password, users[i].password)) { if (users[i].isOnlie == 1) {//判断是否重复登陆 strcpy(sendBuf, "不好意思您重复登陆了!\n"); sendLen = sendto(severSocket, sendBuf, sizeof(sendBuf), 0, (SOCKADDR*)&showMsgAddr, sizeof(showMsgAddr)); return; } else { users[i].isOnlie = 1; onlineCount++; users[i].addr = showMsgAddr; printf("一个客户登陆,客户的ip为:%s----端口号为%d\n", inet_ntoa(showMsgAddr.sin_addr), ntohs(showMsgAddr.sin_port)); sprintf(onlineStr, "%d", onlineCount);//吧int类型的数转为字符串 strcpy(sendBuf, "客户登陆,目前在线人数为 "); strcat(sendBuf, onlineStr); strcat(sendBuf, "\n"); //发送给所有的客户端 for (i = 0; i < userCount; i++) { if (users[i].isOnlie == 1) { sendLen = sendto(severSocket, sendBuf, sizeof(sendBuf), 0, (SOCKADDR*)&users[i].addr, sizeof(users[i].addr)); if (sendLen == SOCKET_ERROR) { printf("发送失败!"); return; } } } return; } } else { strcpy(sendBuf, "密码错误\n"); sendLen = sendto(severSocket, sendBuf, sizeof(sendBuf), 0, (SOCKADDR*)&showMsgAddr, sizeof(showMsgAddr)); return; } } } strcpy(sendBuf, "不存在此用户名,请注册\n"); sendLen = sendto(severSocket, sendBuf, sizeof(sendBuf), 0, (SOCKADDR*)&showMsgAddr, sizeof(showMsgAddr)); return; }}/*注册功能*/void logout() { printf("注册\n"); printf("一个客户正在注册,客户的ip为:%s----端口号为%d\n", inet_ntoa(showMsgAddr.sin_addr), ntohs(showMsgAddr.sin_port)); if (!strcmp("b", recvBuf)) { strcpy(sendBuf, "注册请在发送框输入(b 用户名 密码)按回车\n"); sendLen = sendto(severSocket, sendBuf, sizeof(sendBuf), 0, (SOCKADDR*)&showMsgAddr, sizeof(showMsgAddr)); if (sendLen == SOCKET_ERROR) { printf("发送失败!"); return; } } else { //分割字符串 delimiters = strtok(recvBuf, " "); delimiters = strtok(NULL, " "); strcpy(username, delimiters);//拿到注册的username delimiters = strtok(NULL, " "); strcpy(password, delimiters);//拿到注册的密码 /*判断是不是已经存在用户名*/ for (i = 0; i < userCount; i++) { if(!strcmp(username, users[i].username) ){ strcpy(sendBuf, "用户名已经存在!\n"); sendLen = sendto(severSocket, sendBuf, sizeof(sendBuf), 0, (SOCKADDR*)&showMsgAddr, sizeof(showMsgAddr)); if (sendLen == SOCKET_ERROR) { printf("发送失败!"); return; } } } //如果没有存在就给结构体赋值 strcpy(users[i].username, username); strcpy(users[i].password, password); users[i].addr = showMsgAddr; userCount++; strcpy(sendBuf, "注册成功,请登陆\n"); sendLen = sendto(severSocket, sendBuf, sizeof(sendBuf), 0, (SOCKADDR*)&showMsgAddr, sizeof(showMsgAddr)); if (sendLen == SOCKET_ERROR) { printf("发送失败!"); return; } }}/*注销登陆*/void LogOff() { /*判断发出注销功能的是哪一个用户*/ strcpy_s(clientIP, 1024, inet_ntoa(showMsgAddr.sin_addr)); for (i = 0; i < userCount; i++) { strcpy_s(addrIP, 1024, inet_ntoa(users[i].addr.sin_addr)); if (!strcmp(clientIP, addrIP)) { users[i].isOnlie = 0; strcpy(sendBuf, "成功退出! "); sendLen = sendto(severSocket, sendBuf, sizeof(sendBuf), 0, (SOCKADDR*)&showMsgAddr, sizeof(showMsgAddr)); } } onlineCount--;//在线人数-1 sprintf(onlineStr, "%d", onlineCount); strcpy(sendBuf, "有一个用户退出,目前在线人数为 "); strcat(sendBuf, onlineStr); strcat(sendBuf, "\n"); for (i = 0; i < userCount; i++) { if (users[i].isOnlie == 1) { sendLen = sendto(severSocket, sendBuf, sizeof(sendBuf), 0, (SOCKADDR*)&users[i].addr, sizeof(users[i].addr)); if (sendLen == SOCKET_ERROR) { printf("发送失败!"); return; } } }}/*群聊功能*/void groupChar() { //printf("群聊\n"); if (!strcmp("c", recvBuf)) { strcpy(sendBuf, "请畅所欲言吧!\n"); sendLen = sendto(severSocket, sendBuf, sizeof(sendBuf), 0, (SOCKADDR*)&showMsgAddr, sizeof(showMsgAddr)); if (sendLen == SOCKET_ERROR) { printf("发送失败!"); return; } } else { strcpy_s(clientIP, 1024, inet_ntoa(showMsgAddr.sin_addr)); for (i = 0; i < userCount; i++) { strcpy_s(addrIP, 1024, inet_ntoa(users[i].addr.sin_addr)); if (!strcmp(clientIP, addrIP)) { strcpy(username, users[i].username); } } strcat(username, " : "); strcat(username, recvBuf); strcpy(recvBuf, username); //取出users里面的每一个用户 for (i = 0; i < userCount; i++) { if (users[i].isOnlie == 1) { sendLen = sendto(severSocket, recvBuf, sizeof(recvBuf), 0, (SOCKADDR*)&users[i].addr, sizeof(users[i].addr)); if (sendLen == SOCKET_ERROR) { printf("发送失败!"); return; } } } }}/*私聊功能*/void privateChat() { printf("私聊\n");}void main() { if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { printf("协议栈加载失败!"); return; } //创建socket severSocket = socket(AF_INET, SOCK_DGRAM, 0); if (severSocket == INVALID_SOCKET) { printf("套接口创建失败!"); return; } //初始化地址 serverAddr.sin_family = AF_INET; serverAddr.sin_port = htons(8888); serverAddr.sin_addr.s_addr = htonl(INADDR_ANY); //绑定套接口 if (bind(severSocket, (LPSOCKADDR)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) { printf("套接口绑定失败!"); return; } clientaddrLen = sizeof(clientAddr); memset(recvBuf, 0, sizeof(recvBuf)); printf("-------------服务器在等待-------------\n"); //开始接收数据 while (1) { recvlen = recvfrom(severSocket, recvBuf, 1024, 0, (SOCKADDR*)&clientAddr, &clientaddrLen); showMsgAddr = clientAddr; showMsgAddr.sin_port = ntohs(6666);//把端口地址改为6666 if (recvlen != 0) { if (recvBuf[0] == 'a') { login(); } else if (recvBuf[0] == 'b') { logout(); } else if(!strcmp(recvBuf, "end")){ LogOff(); } else { groupChar(); } } } closesocket(severSocket); WSACleanup();}
客户端
#include<stdio.h>#include<Winsock2.h>#include<stdlib.h>#pragma comment(lib,"Ws2_32.lib")SOCKET clientSocket;WSADATA wsaData;char sendBuf[1024];struct sockaddr_in serverAddr;int sendLen;//发送数据的长度void main() { //加载协议栈 if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { printf("协议栈加载失败!"); return; } //创建客户端的socket clientSocket = socket(AF_INET, SOCK_DGRAM, 0); if (clientSocket == INVALID_SOCKET) { printf("套接口创建失败!"); return; } //初始化目标服务器的地址 serverAddr.sin_family = AF_INET; serverAddr.sin_port = htons(8888); serverAddr.sin_addr.s_addr = inet_addr("172.18.130.230"); while (1) { printf("输入要发送的数据:"); gets_s(sendBuf, 1024); sendLen = sendto(clientSocket, sendBuf,sizeof(sendBuf), 0, (struct sockaddr*)&serverAddr, sizeof(serverAddr)); if (sendLen == SOCKET_ERROR) { printf("发送失败!"); return; } }}
客户端显示消息端
#include<stdio.h>#include<Winsock2.h>#include<stdlib.h>#pragma comment(lib,"Ws2_32.lib")SOCKET severSocket;WSADATA wsaData;struct sockaddr_in serverAddr, clientAddr;char recvBuf[1024];int recvlen;//接收数据的长度int clientaddrLen;//客户端地址长度void showUI() { printf("------------------------------------------------------------------\n"); printf("-----------------------欢迎来到狒狒聊天室-------------------------\n"); printf("------------------------请输入下列字母----------------------------\n"); printf("------------a:登陆 b:注册 c:群聊 d:私聊 end:退出登陆--------\n"); printf("------------------------------------------------------------------\n");}void main() { if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { printf("协议栈加载失败!"); return; } //创建socket severSocket = socket(AF_INET, SOCK_DGRAM, 0); if (severSocket == INVALID_SOCKET) { printf("套接口创建失败!"); return; } //初始化地址 serverAddr.sin_family = AF_INET; serverAddr.sin_port = htons(6666); serverAddr.sin_addr.s_addr = htonl(INADDR_ANY); //绑定套接口 if (bind(severSocket, (LPSOCKADDR)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) { printf("套接口绑定失败!"); return; } clientaddrLen = sizeof(clientAddr); memset(recvBuf, 0, sizeof(recvBuf)); showUI();//调用显示界面函数 //开始接收数据 while (1) { recvlen = recvfrom(severSocket, recvBuf, 1024, 0, (SOCKADDR*)&clientAddr, &clientaddrLen); if (recvlen != 0) { printf("%s\n", recvBuf); //printf("客户的ip为:%s----端口号为%d", inet_ntoa(clientAddr.sin_addr), ntohs(clientAddr.sin_port)); //发送给客户 //int sendLen = sendto(severSocket, recvBuf, sizeof(recvBuf), 0, (SOCKADDR*)&clientAddr, clientaddrLen); //if (sendLen == SOCKET_ERROR) { // printf("发送失败!"); // break; //} } } closesocket(severSocket); WSACleanup();}
0 0
- 【tcp-ip学习总结】基于udp的多人聊天室,带有登录注册功能
- udp聊天室 带有注册功能
- 【tcp-ip学习总结】基础UDP实现的简单通信功能小程序
- Java 基于Tcp/ip连接的多人交互聊天室(Socket编程)
- 【SOCKET编程】基于C++的TCP/UDP的聊天室
- 多人聊天室(基于Linux的SOCKET UDP编程)
- TCP,UDP,IP总结
- TCP,UDP,IP总结
- 简单的登录、注册以及带有验证码功能
- python: tcp/ip学习、端口号、UDP的发送和接受数据、绑定端口号、模拟聊天室
- Unity基于TCP/IP的小聊天室实现
- 嵌入式每日学习心得 基于TCP/IP的聊天室程序
- TCP/UDP/IP学习
- 聊天室的注册与登录
- 基于UDP的局域网聊天室
- 基于UDP的socket聊天室
- 【tcp-ip学习总结】传输层协议UDP和TCP
- 基于TCP,UDP的网络编程总结
- 浩易南:想创业?给新人的15条建议
- hostapd 调试信息
- 为何响应时间常被测错
- 《剑指Offer》学习笔记--面试题20:顺时针打印矩阵
- 关于android手机mtk平台 信号格数的修改
- 【tcp-ip学习总结】基于udp的多人聊天室,带有登录注册功能
- vim + ctags + cscope + taglist
- 关于cocos2d-x项目导入到eclipse中clean项目时产生的错误
- exe4j安装过程详解
- 11-vmware中安装vm-tools的方法
- NodeJS异常处理uncaughtException篇
- _C_#ifdef
- window7+vs2013+DirectShow(windows sdk v7.1)配置
- 水过一道并查集 hdu1232