網路上發現的控制台聊天程式範例,經修改整理收藏。採用 Winsock API、多執行緒處理收發訊息。
// 2009-06-28
#pragma comment(lib,"ws2_32.lib")
#include <winsock2.h>
#include <stdio.h>
#include <string>
using namespace std;
string strCurMsg = "";
void recvProc(SOCKET sockConnect) {
char msgRcv[100] = {0};
while (true) {
if (SOCKET_ERROR == recv(sockConnect, msgRcv, sizeof(msgRcv), 0)) {
printf("\nHe is leaving");
return;
}
if (msgRcv[0] != '\0') {
strCurMsg.erase(strCurMsg.end()-7, strCurMsg.end());
strCurMsg += "He said: ";
strCurMsg += msgRcv;
strCurMsg += '\n';
strCurMsg += "input: ";
system("cls");
printf("%s", strCurMsg.c_str());
}
}
}
int main(int argc, char* argv[]) {
WORD wVersionRequested = MAKEWORD(1, 1);
WSADATA wsaData;
if (WSAStartup(wVersionRequested, &wsaData) != 0) return 1;
if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1) {
WSACleanup(); return 1;
}
SOCKET sockSrv = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
sockaddr_in addrSrv = {0};
addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(5000);
if (bind(sockSrv, (sockaddr*)&addrSrv, sizeof(sockaddr)) == SOCKET_ERROR) {
printf("bind error"); return 1;
}
if (listen(sockSrv, 5) == SOCKET_ERROR) {
printf("listen error"); return 1;
}
SOCKADDR_IN addrClient;
int len = sizeof(sockaddr);
while (true) {
printf("Waiting ...");
SOCKET sockConnect = accept(sockSrv, (sockaddr*)&addrClient, &len);
if (sockConnect == INVALID_SOCKET) {
printf("invalid socket"); return 0;
} else {
printf("He is coming\n");
}
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)recvProc, (void*)sockConnect, 0, NULL);
while (true) {
char buf[100] = {0};
strCurMsg += "input: ";
system("cls");
printf("%s", strCurMsg.c_str());
gets_s(buf, 100);
strCurMsg.erase(strCurMsg.end()-7, strCurMsg.end());
strCurMsg += "You said:";
strCurMsg += buf;
strCurMsg += '\n';
send(sockConnect, buf, sizeof(buf), 0);
}
closesocket(sockConnect);
}
WSACleanup();
return 0;
}
// 2009-06-28
#pragma comment(lib,"ws2_32.lib")
#include <winsock2.h>
#include <stdio.h>
#include <string>
using namespace std;
string strCurMsg = "";
void recvProc(SOCKET sockClient) {
char msgRcv[100] = {0};
while (true) {
if (SOCKET_ERROR == recv(sockClient, msgRcv, sizeof(msgRcv), 0)) {
printf("\nHe is leaving");
return;
}
if (msgRcv[0] != '\0') {
strCurMsg.erase(strCurMsg.end()-7, strCurMsg.end());
strCurMsg += "He said: ";
strCurMsg += msgRcv;
strCurMsg += '\n';
strCurMsg += "input: ";
system("cls");
printf("%s", strCurMsg.c_str());
}
}
}
int main(int argc, char* argv[]) {
WORD wVersionRequested = MAKEWORD(1, 1);
WSADATA wsaData;
if (WSAStartup(wVersionRequested, &wsaData) != 0) return 1;
if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1) {
WSACleanup(); return 1;
}
SOCKET sockClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
SOCKADDR_IN addrSrv = {0};
addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(5000);
if (connect(sockClient, (sockaddr*)&addrSrv, sizeof(sockaddr)) == SOCKET_ERROR) {
printf("connected failed\n"); return 1;
} else {
printf("connect OK\n");
}
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)recvProc, (void*)sockClient, 0, NULL);
while (true) {
char buf[100] = {0};
strCurMsg += "input: ";
system("cls");
printf("%s", strCurMsg.c_str());
gets_s(buf, 100);
strCurMsg.erase(strCurMsg.end()-7, strCurMsg.end());
strCurMsg += "You said:";
strCurMsg += buf;
strCurMsg += '\n';
send(sockClient, buf, sizeof(buf), 0);
}
closesocket(sockClient);
WSACleanup();
return 0;
}
注意:原始碼中 gets 已替換為較安全的 gets_s,實際使用建議進一步加強錯誤處理與資源管理。