1 Star 0 Fork 0

chenxfeng/chatting_program

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
client_ver2_0.c 12.59 KB
一键复制 编辑 原始数据 按行查看 历史
chenxfeng 提交于 2017-04-24 19:41 . Add files via upload
// Client.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <Winsock2.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <process.h>
#include "conio.h"
#pragma comment(lib, "ws2_32.lib")
#define STRLEN 4096
#define SERVPORT 5400
#define CLIUSERLEN 8
#define WSVERS MAKEWORD(2, 2)
//#define _WINSOCK_DEPRECATED_NO_WARNINGS
#define USER_NOT_EXISTS "400"
#define INCORRECT_PASSWORD "401"
#define USER_NOT_FOUND "4040"
#define NOT_ONLINE "4041"
#define REJECT_CHATTING "4042"
#define IS_ONLINE "2000"
#define START_CHATTING "2001"
unsigned WINAPI sendmsg(void * linksock);
unsigned WINAPI recvmsg(void * linksock);
char tempBuf[STRLEN]; // global string buffer
int recvThreadBlock = 0;
void testSend(int messageLen);
int logIn(SOCKET linksock);
void oneToOneChatStart(SOCKET linksock);
void chat(SOCKET linksock);
int main(int argc, char *argv[]) {
SOCKET cli;
struct sockaddr_in servSockIn;
HANDLE hsendThread, hrecvThread;
WSADATA wsadata;
int recvMessageLen;
if (WSAStartup(WSVERS, &wsadata) != 0) {
printf("failed to load win socket\n");
return 1;
}
// server address
memset(&servSockIn, 0, sizeof(servSockIn));
servSockIn.sin_family = AF_INET;
servSockIn.sin_addr.s_addr = inet_addr(argv[1]);
servSockIn.sin_port = htons(SERVPORT);
// create socket
cli = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (cli == INVALID_SOCKET) {
printf("socket() failed: %d\n", WSAGetLastError());
return 1;
}
// connect to server
printf("connect to %s:%d\n", inet_ntoa(servSockIn.sin_addr), ntohs(servSockIn.sin_port));
if (connect(cli, (SOCKADDR*)&servSockIn, sizeof(servSockIn)) == INVALID_SOCKET) {
printf("connection failed: %d\n", WSAGetLastError());
return 1;
}
else {
printf("connected...\n");
}
// log in
if (logIn(cli) < 0) {
// log in failed.
printf("log in failed. This cli will quit.\n");
return 1;
}
// get online user list
memset(&tempBuf, 0, sizeof(tempBuf));
recvMessageLen = recv(cli, tempBuf, sizeof(tempBuf), 0);
if (recvMessageLen > 0) printf("%s", tempBuf);
// chating
hsendThread = (HANDLE)_beginthreadex(NULL, 0, &sendmsg, (void *)&cli, 0, NULL);
hrecvThread = (HANDLE)_beginthreadex(NULL, 0, &recvmsg, (void *)&cli, 0, NULL);
WaitForSingleObject(hsendThread, INFINITE);
WaitForSingleObject(hrecvThread, INFINITE);
// log out
closesocket(cli);
WSACleanup();
return 0;
}
// send-message thread
unsigned WINAPI sendmsg(void * linksock) {
SOCKET hsock = *((SOCKET*)linksock);
char wBuf[STRLEN];
while (true) {
fputs("Please input a function: \n", stdout);
fputs("'quit' to escape\n", stdout);
fputs("'chat' someone \n", stdout);
fputs("'call' someone \n", stdout);
fputs("'list' all the users \n", stdout);
fgets(wBuf, STRLEN, stdin);
// confirm chatting request
if (strstr(wBuf, "chat confirm\n") != NULL) {
// confirm to start chatting by request
memset(wBuf, 0, sizeof(wBuf));
sprintf(wBuf, "chat confirm");
int messageLen = send(hsock, wBuf, strlen(wBuf), 0);
testSend(messageLen);
messageLen = send(hsock, wBuf, strlen(wBuf), 0);
testSend(messageLen);
oneToOneChatStart(hsock);
}
if (strstr(wBuf, "chat reject\n") != NULL) {
memset(wBuf, 0, sizeof(wBuf));
sprintf(wBuf, "chat reject");
int messageLen = send(hsock, wBuf, strlen(wBuf), 0);
testSend(messageLen);
messageLen = send(hsock, wBuf, strlen(wBuf), 0);
testSend(messageLen);
}
// request to chat with someone
if (strstr(wBuf, "chat\n") != NULL) {
chat(hsock);
}
else {
// request to call
// if (strncmp(wBuf, "call\n", 7) == 0) {
// call(hsock);
// }
// request to list
// if (strncmp(wBuf, "list\n", 7) == 0) {
// list(hsock);
// }
int messageLen = send(hsock, wBuf, strlen(wBuf), 0);
testSend(messageLen);
// log out
if (strncmp(wBuf, "quit\n", 7) == 0) {
printf("log out successfully. \n");
break;
}
}
}
closesocket(hsock);
return 0;
}
// recv-message thread
unsigned WINAPI recvmsg(void * linksock) {
SOCKET lsock = *((SOCKET*)linksock);
char message[STRLEN + 10];
char recvreq[STRLEN + 1];
struct sockaddr_in cln_addr;
int cln_addr_len;
// memset(&cln_addr, 0, sizeof(cln_addr));
// cln_addr_len = sizeof(cln_addr);
// int ret = getsockname(lsock, (sockaddr*)&cln_addr, &cln_addr_len);
// sprintf(recvreq, "user IP: %s port: %d %s", inet_ntoa(cln_addr.sin_addr), cln_addr.sin_port, message);
while (true) {
// block for send thread
while (recvThreadBlock) {
continue;
}
memset(message, 0, STRLEN);
int recvlen = recv(lsock, message, STRLEN, 0);
if (recvlen == SOCKET_ERROR || recvlen == 0) {
break;
}
else if (recvlen > 0) {
message[recvlen] = '\0';
// if (strstr(message, recvreq) != NULL)
// break;
printf("%s", message);
}
}
closesocket(lsock);
return 0;
}
void testSend(int messageLen) {
switch (messageLen) {
case SOCKET_ERROR: printf("send() failed: %d\n", WSAGetLastError());
case 0: break;
default: printf("send successfully. \n", messageLen);
}
return;
}
int logIn(SOCKET linksock) {
SOCKET lsock = linksock;
char recvmsg[STRLEN];
char sendmsg[STRLEN];
struct sockaddr_in cln_addr;
int cln_addr_len;
int logState;
// send username
memset(sendmsg, 0, sizeof(sendmsg));
fputs("Please input username: ", stdout);
fgets(sendmsg, sizeof(sendmsg), stdin);
// strncpy(sendmsg, username, 5);
// printf("%s\n", sendmsg);
int messageLen = send(lsock, sendmsg, strlen(sendmsg), 0);
testSend(messageLen);
// recv reply
memset(recvmsg, 0, sizeof(recvmsg));
int recvlen = recv(lsock, recvmsg, sizeof(recvmsg), 0);
if (recvlen == 0 || recvlen == SOCKET_ERROR) {
memset(sendmsg, 0, sizeof(sendmsg));
sprintf(sendmsg, "log in failed. \n");
printf("%s", sendmsg);
return -1;
}
else if (recvlen > 0) {
// user not exists.
logState = (strstr(recvmsg, USER_NOT_EXISTS) != NULL);
switch (logState) {
case 1: printf("user not exists. \n"); return -1; break;
default: printf("user found. \n"); printf("%s", recvmsg);
}
// send password
memset(sendmsg, 0, sizeof(sendmsg));
fgets(sendmsg, sizeof(sendmsg), stdin);
// strncpy(sendmsg, password, 5);
// printf("%s\n", sendmsg);
messageLen = send(lsock, sendmsg, strlen(sendmsg), 0);
testSend(messageLen);
memset(recvmsg, 0, sizeof(recvmsg));
recvlen = recv(lsock, recvmsg, sizeof(recvmsg), 0);
if (recvlen == 0 || recvlen == SOCKET_ERROR) {
memset(sendmsg, 0, sizeof(sendmsg));
sprintf(sendmsg, "log in failed. \n");
printf("%s", sendmsg);
return -1;
}
else if (recvlen > 0) {
// wait for reply
logState = (strstr(recvmsg, INCORRECT_PASSWORD) != NULL);
switch (logState) {
case 1: printf("incorrect password. \n"); return -1; break;
default: printf("correct password. \n");
}
printf("%s", recvmsg);
return 1;
}
}
}
void chat(SOCKET linksock) {
SOCKET lsock = linksock;
char wBuf[STRLEN];
char rBuf[STRLEN];
int messageLen;
int recvlen;
recvThreadBlock = 1; // block recv thread
// send chat request
memset(wBuf, 0, sizeof(wBuf));
sprintf(wBuf, "chat");
messageLen = send(lsock, wBuf, strlen(wBuf), 0);
testSend(messageLen);
// wait for reply from server
memset(rBuf, 0, sizeof(rBuf));
recvlen = recv(lsock, rBuf, sizeof(rBuf), 0);
// recv response
if (recvlen == 0 || recvlen == SOCKET_ERROR) {
printf("start chatting failed: response not received. \n");
return;
}
else if (recvlen > 0) {
rBuf[recvlen] = '\0';
printf("%s", rBuf);
}
// send choice
memset(wBuf, 0, sizeof(wBuf));
fgets(wBuf, STRLEN, stdin);
messageLen = send(lsock, wBuf, strlen(wBuf), 0);
testSend(messageLen);
if (strstr(wBuf, "one") != NULL) {
// one-to-one chatting
// wait for destination username request
memset(rBuf, 0, sizeof(rBuf));
recvlen = recv(lsock, rBuf, sizeof(rBuf), 0);
// recv destination
if (recvlen == 0 || recvlen == SOCKET_ERROR) {
printf("start chatting failed: destination request not received. \n");
recvThreadBlock = 0; // release lock
return;
}
else if (recvlen > 0) {
rBuf[recvlen] = '\0';
printf("%s", rBuf);
}
// send destination username
memset(wBuf, 0, sizeof(wBuf));
fgets(wBuf, STRLEN, stdin);
messageLen = send(lsock, wBuf, strlen(wBuf), 0);
testSend(messageLen);
wBuf[messageLen - 1] = '\0';
// wait for destination-username response
memset(rBuf, 0, sizeof(rBuf));
recvlen = recv(lsock, rBuf, sizeof(rBuf), 0);
// diff response code
if (recvlen == 0 || recvlen == SOCKET_ERROR) {
printf("start chatting failed: destination response not received. \n");
recvThreadBlock = 0; // release lock
return;
}
else if (recvlen > 0) {
rBuf[recvlen] = '\0';
// destination user not found
if (strstr(rBuf, USER_NOT_FOUND) != NULL) {
printf("user %s is not found. \n", wBuf);
recvThreadBlock = 0; // release lock
return;
}
// destination user not online
else if (strstr(rBuf, NOT_ONLINE) != NULL) {
printf("user %s isn't online. \n", wBuf);
recvThreadBlock = 0; // release lock
return;
}
else if (strstr(rBuf, IS_ONLINE) != NULL) {
printf("user %s is online. \n", wBuf);
// wait for chat confirmed
memset(rBuf, 0, sizeof(wBuf));
recvlen = recv(lsock, rBuf, sizeof(rBuf), 0);
if (recvlen == 0 || recvlen == SOCKET_ERROR) {
printf("start chatting failed: chatting confirm not received. \n");
recvThreadBlock = 0; // release lock
return;
}
else if (recvlen > 0) {
// chatting rejected
if (strstr(rBuf, REJECT_CHATTING) != NULL) {
printf("but rejected your chatting request. \n");
recvThreadBlock = 0; // release lock
return;
}
else if (strstr(rBuf, START_CHATTING) != NULL) {
// one-to-one chatting
recvThreadBlock = 0;
oneToOneChatStart(lsock);
}
}
}
}
}
else if (strstr(rBuf, "group") != NULL) {
// more-to-more chatting
//
} else {
printf("start chatting failed: chat-type not supported. \n");
}
recvThreadBlock = 0; // release lock
return;
}
void oneToOneChatStart(SOCKET linksock) {
SOCKET lsock = linksock;
char wBuf[STRLEN];
int messageLen;
while (true) {
fputs("chatting...('quit' ot quit)\n", stdout);
fgets(wBuf, STRLEN, stdin);
int messageLen = send(lsock, wBuf, strlen(wBuf), 0);
testSend(messageLen);
// quit chatting
if (strncmp(wBuf, "quit\n", 7) == 0) {
printf("you leave chatting. \n");
break;
}
}
return;
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/chenxfeng/chatting_program.git
git@gitee.com:chenxfeng/chatting_program.git
chenxfeng
chatting_program
chatting_program
master

搜索帮助

23e8dbc6 1850385 7e0993f3 1850385