[Windows网络编程课设]南工程聊天室客户端源码
2016-09-20 18:46
309 查看
南工程聊天室客户端源码
南京工程学院通信工程学院的《Windows网络编程》一课的课程设计源码,聊天室的搭构需要服务器和客户端。服务器源码请看上一篇博文,都有贴出。备注也很详细,可以参考一下。不过作为聊天室功能也很多的,我这里贴出的代码功能实现的并不全面。如果有同学对此作出改进,希望可以交流一下。
MyMsg.h
MyTcp.cpp
MyTcp.h
MyTools.cpp
TalkClient.cpp
TalkClientService.cpp
char buf[100] = { 0 };sprintf(buf, "%s", msg->qq);printMsg("在线的QQ好友: \n");printMsg(buf);printf("\n");status = STUS_LOGINED;}
TalkClientService.h
南京工程学院通信工程学院的《Windows网络编程》一课的课程设计源码,聊天室的搭构需要服务器和客户端。服务器源码请看上一篇博文,都有贴出。备注也很详细,可以参考一下。不过作为聊天室功能也很多的,我这里贴出的代码功能实现的并不全面。如果有同学对此作出改进,希望可以交流一下。
MyMsg.h
#pragma once /************************************************************ * 文件名:MyMsg.h * 描述: 服务器和客户端共用的头文件,消息定义 *************************************************************/ #ifndef _MYMSG_H_ #define _MYMSG_H_ enum { LOGIN_MSG, //登录 LOGIN_MSG_RES, //登录响应 QUERY_FQQ, //查询单个好友QQ QUERY_FQQ_RES, //查询单个好友QQ的响应 TALK_MSG, //聊天 REQUEST_ALL_FRD, //请求所有qq好友信息 APPLY_ALL_FRD //应答所有qq好友信息 }; struct LoginMsg { unsigned char id; //消息编号 char qq[6]; //登录ID号 }; struct LoginMsgResponse { unsigned char id; //消息编号 unsigned char isOK; char reason[100]; //如果失败,则在此写入失败原因 }; struct FriendQqMsg { unsigned char id; //消息编号 char qq[6]; }; struct FriendQqMsgResponse { unsigned char id; //消息编号 unsigned char isOK; }; struct TalkMsg { unsigned char id; //消息编号 char qq[6]; char fqq[6]; char info[200]; }; struct RequestAllFriend { unsigned char id; //消息编号 }; struct AllFriendMsg { unsigned char id; //消息编号 char qq[6]; }; #endif
MyTcp.cpp
/************************************************************ * 文件名:MyTCP.cpp * 描述: TCP/IP通信socket封装 *************************************************************/ #include <stdio.h> #include <WinSock2.h> #include "MyTools.h" #pragma comment (lib, "ws2_32.lib") #define PORT 5001 int ls; //侦听套接字 int flag;//记录服务器或是客户端的标志 /* 描述: 初始化服务器或客户端, 该函数在使用中必需首先调用,客户端和服务器 */ int initSock(int IsServer) { WSADATA data; if (WSAStartup(1, &data) <0) printMsgExit("call WSAStartup() failure!"); ls = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (ls < 0) printMsgExit("创建套接字失败!"); flag = IsServer; if (IsServer != 0) {//服务器 struct sockaddr_in servAddr; memset(&servAddr, 0, sizeof(servAddr)); servAddr.sin_family = AF_INET; servAddr.sin_addr.s_addr = htonl(INADDR_ANY); servAddr.sin_port = htons(PORT); if (bind(ls, (struct sockaddr *)&servAddr, sizeof(servAddr))<0) { printMsg("bind套接字失败!\n"); return -1; } if (listen(ls, 10)<0) { printMsg("listen套接字失败!\n"); return -1; } } return 0; } /* 描述: 仅用于客户端, 连接服务器 */ int tcpConnect(const char *serverIP, unsigned short port) { struct sockaddr_in servAddr; memset(&servAddr, 0, sizeof(servAddr)); servAddr.sin_family = AF_INET; servAddr.sin_addr.s_addr = inet_addr(serverIP); servAddr.sin_port = htons(port); if (connect(ls, (struct sockaddr *)&servAddr, sizeof(servAddr))<0) { printMsgExit("连接服务器失败!\n"); } return ls; } /* 描述: 发送数据 */ int tcpSend(unsigned int sock, const char *sendBuf, int sendBufLen) { int len = send(sock, sendBuf, sendBufLen, 0); return len; } /* 描述: 接收数据 */ int tcpRecv(unsigned int sock, char *recvBuf, int recvBufLen) { int len = recv(sock, recvBuf, recvBufLen, 0); return len; } void tcpClose(unsigned int sock) { closesocket(sock); WSACleanup(); }
MyTcp.h
#pragma once /************************************************************ * 文件名:MyTCP.h * 描述: TCP通信头文件 *************************************************************/ #ifndef _MYTCP_H_ #define _MYTCP_H_ int initSock(int IsServer); int tcpConnect(const char *serverIP, unsigned short port); int tcpAccept(); int tcpSend(unsigned int sock, const char *sendBuf, int sendBufLen); int tcpRecv(unsigned int sock, char *recvBuf, int recvBufLen); void tcpClose(unsigned int sock); #endif
MyTools.cpp
/************************************************************ * 文件名:MyTools.cpp * 描述: 共用的文件,工具函数定义 *************************************************************/ #include <stdio.h> #include <stdlib.h> #include "MyTools.h" extern int flag; void printMsg(const char * msg) { if (flag) printf("\t【南工服务器豪华版】%s", msg); else printf("\t【南工客户端豪华版】%s", msg); } void printInt(int value) { if (flag) printf("\t【南工服务器豪华版】%d", value); else printf("\t【南工客户端豪华版】%d", value); } void printMsgExit(const char * msg) { printMsg(msg); exit(0); } void printIntExit(int value) { printInt(value); exit(0); }MyTools.h
#pragma once /************************************************************ * 文件名:MyTools.h * 描述:工具函数定义 *************************************************************/ #ifndef _MYTOOLS_H_ #define _MYTOOLS_H_ void printMsgExit(const char * msg); void printMsg(const char * msg); void printInt(int value); void printIntExit(int value); #endif
TalkClient.cpp
/************************************************************ * 文件名:TalkClient.cpp * 描述: 客户端入口,界面操作 *************************************************************/ #include <stdio.h> #include <Windows.h> #include "TalkClientService.h" void displayMenu(); void exitProc(); void defProc(); void procMenu(); char serverip[6]; int main(int argc, char *argv[]) { if (argc < 2) { printf("请输入服务器的IP地址。。。\n"); return 0; } strcpy(serverip, argv[1]); displayMenu(); procMenu(); while (1) Sleep(10000); } char ch; //菜单选择 void displayMenu() { static int t = 1; if (t++ == 1) { printf("\n\n\n\n\n"); printf("\n\t @ @ "); printf("\n\t @ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @ "); printf("\n\t @ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @ "); printf("\n\t @ ** ** ********** ** ** ******** ** ** @ "); printf("\n\t @ ** ** ** ** ** ** ** ** ** @ "); printf("\n\t @ ** ** ** ** ** ** ** ** ** @ "); printf("\n\t @ ********** ********** ** ** ** ** ** ** @ "); printf("\n\t @ ** ** ** ** ** ** ** ** ** @ "); printf("\n\t @ ** ** ** ** ** ** ** @ "); printf("\n\t @ ** ** ********** ******** ******** ******** @@ @@ @ "); printf("\n\t @ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @ "); printf("\n\t @ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^@ "); printf("\n\t @ @ "); printf("\n -----By Hins "); printf("\n\n\n\n\n\t\tPress 'Enter' to enter the menu......"); /*按任一键进入主菜单*/ } getchar(); /*从键盘读取一个字符,但不显示于屏幕*/ system("cls"); /*清屏*/ printf("\n"); printf("\n"); printf("\n"); printf("\t************************************************\n"); printf("\t* *\n"); printf("\t* 南工2016聊天客户端程序 *\n"); printf("\t* Version 2.1 豪华版 *\n"); printf("\t* *\n"); printf("\t* *\n"); printf("\t* *\n"); printf("\t* 1) 登录(L) *\n"); printf("\t* 2) 退出(e) *\n"); printf("\t* by---HinsShwan *\n"); printf("\t************************************************\n"); printf("\n"); connectServer(); printf("\t您的选择是:"); ch = getchar(); } void procMenu() { switch (ch) { case 'l': case 'L': case '1': statusConnected(); break; case 'e': case 'E': case '2': exitProc(); break; default: defProc(); } } void exitProc() { printf("\t客户端程序已经终止!\n"); exit(0); } void defProc() { printf("\t 输入字符错误!\n"); }
TalkClientService.cpp
/************************************************************ * 文件名:TalkClientService.cpp * 描述: 客户端业务实现 *************************************************************/ #include "MyTCP.h" #include "MyTools.h" #include "TalkClientService.h" void myRecvThread(); #define PORT 5001 extern char serverip[6]; char qq[6] = { 0 }; char fqq[6] = { 0 }; int sock; int status = STUS_START; void mainProc() { while (1) { switch (status) { case STUS_CONNECTED: statusConnected(); break; case STUS_WAIT_LOGIN_RES: printMsg("等待服务器响应..........\n"); Sleep(1000); break; case STUS_LOGINED: statusLogined(); break; case STUS_WAIT_QUERY_FQQ_RES: printMsg("等待服务器响应..........\n"); Sleep(1000); break; case STUS_TALK: statusTalk(); break; case STUS_WAIT_QUERY_ALLQQ_RES: printMsg("等待服务器响应..........\n"); Sleep(1000); break; } } } void statusTalk() { printMsg("退出聊天(Exit) 我说>>"); setbuf(stdin, NULL); //清空键盘缓冲区 char buf[1024] = { 0 }; gets_s(buf); if (strcmp(buf, "Exit") == 0) { printMsg("客户端已经退出!\n"); statusLogined(); } else { struct TalkMsg msg; msg.id = TALK_MSG; strcpy(msg.qq, qq); strcpy(msg.fqq, fqq); strcpy(msg.info, buf); status = 5; tcpSend(sock, (const char *)&msg, sizeof(msg)); } return; } void statusLogined() { char buf0[10] = { 0 }; int rt = 0; while (rt == 0) { memset(buf0, 0, sizeof(buf0)); printMsg("显示在线好友(L)|找好友聊天(T)|退出(E) 默认(T)>>"); setbuf(stdin, NULL); //清空键盘缓冲区 gets_s(buf0); if (strcmp(buf0, "T") == 0 || strcmp(buf0, "t") == 0) { printMsg("选择聊天好友......\n"); while (1) { printMsg("输入聊天好友QQ号(最多不超过5位): 退出请输入“quit”"); char tmp[1024]; scanf("%s", tmp); if (strlen(tmp) > 5) { printMsg("您输入的qq号长度大于5个,请重新输入\n"); } else if (strcmp(tmp, qq) == 0) { printMsg("您输入的qq号是自己号码,难道您要自言自语吗?::) 请重新输入\n"); } else if (strcmp(tmp, "quit") == 0) break; else { //发送要聊天的好友QQ号给服务器 struct FriendQqMsg msg; msg.id = QUERY_FQQ; strcpy(msg.qq, tmp); strcpy(fqq, tmp); status = STUS_WAIT_QUERY_FQQ_RES; tcpSend(sock, (const char *)&msg, sizeof(msg)); rt = 1; break; } } } else if (strcmp(buf0, "L") == 0 || strcmp(buf0, "l") == 0) { char buf2[10] = { 0 }; memset(buf2, 0, sizeof(buf2)); struct RequestAllFriend res; res.id = REQUEST_ALL_FRD; memcpy(buf2, &res, sizeof(res)); tcpSend(sock, (const char*)buf2, sizeof(buf2)); status = STUS_WAIT_QUERY_ALLQQ_RES; Sleep(100); } else if (strcmp(buf0, "E") == 0 || strcmp(buf0, "e") == 0) { printMsg("客户端已经退出!\n"); exit(0); } else { printMsg("输入内容错误(手抖了吧-_-),请重新输入\n"); } }; } void connectServer() { printMsg("开始连接服务器......\n"); initSock(0); //客户端 sock = tcpConnect(serverip, PORT); printMsg("连接服务器成功!\n"); //创建一个线程用于接收服务器发送的信息 DWORD threadId; CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)myRecvThread, NULL, 0, &threadId); } //创建接收线程专用于接收并处理服务器返回的收数据 void myRecvThread() { char buf[1024] = { 0 }; while (1) { memset(buf, 0, sizeof(buf)); tcpRecv(sock, buf, sizeof(buf)); unsigned char id = (unsigned char)buf[0]; switch (id) { case LOGIN_MSG_RES: procLoginMsgResponse((struct LoginMsgResponse *)buf); break; case QUERY_FQQ_RES: procFriendQqMsgResponse((struct FriendQqMsgResponse *)buf); break; case TALK_MSG: procTalkMsg((struct TalkMsg *)buf); break; case APPLY_ALL_FRD: procApplyAllFriend((struct AllFriendMsg *)buf); break; } } sprintf(buf, "结束myRecvThread线程:%d.........\n"); printMsg(buf); exit(0); } void statusConnected() { printMsg("\n\t请输入登录信息\n"); while (1) { printMsg("本机的QQ号(最多不超过5位数字):"); char tmp[1024]; scanf("%s", tmp); int i; if (strlen(tmp)>5) { printMsg("您输入的qq号长度大于5个,请重新输入\n"); continue; } for (i = 0;i<strlen(tmp);i++) { if (tmp[i] >= '0' && tmp[i] <= '9') { continue; } else break; } if (i == strlen(tmp)) { strcpy(qq, tmp); break; } else { printMsg("输入信息有误,请重新输入\n"); continue; } } struct LoginMsg msg; msg.id = LOGIN_MSG; status = STUS_WAIT_LOGIN_RES; strcpy(msg.qq, qq); tcpSend(sock, (const char *)&msg, sizeof(msg)); mainProc(); //进入主处理程序 return; } void procLoginMsgResponse(struct LoginMsgResponse *msg) { if (msg->isOK == 1) { printMsg("登录成功!\n"); status = STUS_LOGINED;//已登录状态 } else { printMsg("登录失败!\n"); printMsgExit(msg->reason); printf("\n"); } } void procFriendQqMsgResponse(struct FriendQqMsgResponse *msg) { if (msg->isOK == 1) { printMsg("好友目前在线,可以开始聊天...\n"); status = STUS_TALK; } else { printMsg("好友不存在啊,再换个人试试!\n"); status = STUS_LOGINED; } } void procTalkMsg(struct TalkMsg *msg) { char buf[1024] = { 0 }; if (strcmp(msg->qq, fqq) == 0) {//表示是自己发起的聊天,仅仅显示信息即可 printf("\n"); sprintf(buf, "%s说>>%s", fqq, msg->info); printMsg(buf); } else {//是陌生人发起的聊天 printf("\n"); sprintf(buf, "%s说>>%s", msg->qq, msg->info); printMsg(buf); } } void procApplyAllFriend(struct AllFriendMsg *msg) {<pre name="code" class="html">#pragma once /************************************************************ * 文件名:TalkClientService.h * 描述: 客户端业务层函数声明 *************************************************************/ #ifndef _TALKCLIENTSERVICE_H_ #define _TALKCLIENTSERVICE_H_ #include <Windows.h> #include <stdio.h> #include <string.h> #include <stdlib.h> #include "MyMsg.h" void connectServer(); void procLoginMsgResponse(struct LoginMsgResponse *msg); void procFriendQqMsgResponse(struct FriendQqMsgResponse *msg); void procTalkMsg(struct TalkMsg *msg); void statusConnected(); void statusLogined(); void statusTalk(); void procApplyAllFriend(struct AllFriendMsg *msg); /** 客户端状态 **/ enum { STUS_START, STUS_CONNECTED, STUS_WAIT_LOGIN_RES, STUS_LOGINED, STUS_WAIT_QUERY_FQQ_RES, STUS_TALK, STUS_WAIT_QUERY_ALLQQ_RES }; #endif
char buf[100] = { 0 };sprintf(buf, "%s", msg->qq);printMsg("在线的QQ好友: \n");printMsg(buf);printf("\n");status = STUS_LOGINED;}
TalkClientService.h
相关文章推荐
- java-模拟tomcat服务器
- Linux socket 初步
- 如何组织构建多文件 C 语言程序(二)
- 如何重装TCP/IP协议
- Windows 8 官方高清壁纸欣赏与下载
- 谁是桌面王者?Win PK Linux三大镇山之宝
- 对《大家都在点赞 Windows Terminal,我决定给你泼一盆冷水》一文的商榷
- Windows Clang开发环境备忘
- 从Windows系统下访问Linux分区相关软件
- 如何写好 C main 函数
- 对《大家都在点赞 Windows Terminal,我决定给你泼一盆冷水》一文的商榷
- Windows下搭建本地SVN服务器
- 使用Windows原生命令一键清空剪贴板
- windows用windeployqt发布qt quick application程序
- 利用开源软件打造自己的全功能远程工具
- Windows 8虚拟机不能全屏的解决方法
- 虚拟化基础架构Windows 2008篇之1-虚拟化基础服务概述
- 虚拟化基础架构Windows 2008篇之5-安装Windows部署服务