客户端的程序结构前半部分与服务器端基本相同,后半部分也相对简单。相关函数的解释可以参考前文服务器端的内容。有关客户端的内容除个别地方外,就不再做长篇大论的解释。强调一点,如果将此程序移到其它电脑上运行,编译需要release模式,具体做法可以参考上一篇。
客户端程序简介如下:
一、头文件部分
#include<iostream>
using namespace std;
#include<thread>
#include <WinSock2.h>
#pragma comment(lib,"ws2_32.lib")
#pragma warning (disable: 4996) //解决C4996报错问题
二、声明函数及全局变量
void clientRecv();
void clientSend();
SOCKET pubServerSock; //服务器端SOCKET对象(客户端需与服务器端联系)
三、主函数编写(客户端与服务器端链接的具体步骤)
int main(void)
{
步骤1. 窗口设置
system("color 1A");system("title Client Station");system("mode con cols=60 lines=30");
步骤2. 打开网络库
WORD wdVersion = MAKEWORD(2, 2); WSADATA wdSockMsg;int nRes = WSAStartup(wdVersion, &wdSockMsg);if (0 != nRes){cout << "网络库打开过程失败,程序即将结束!" << endl;system("pause");return 0; }
步骤3. 检验网络库版本号
if (2 != HIBYTE(wdSockMsg.wVersion) || 2 != LOBYTE(wdSockMsg.wVersion)){cout << "网络库版本有误,程序即将结束!" << endl;system("pause");WSACleanup();return 0;}
步骤4. 创建服务器端SOCKET对象(便于客户端联系服务器)
pubServerSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);if (INVALID_SOCKET == pubServerSock){cout << "创建服务器端SOCKET对象失败,程序即将结束!" << endl;system("pause");WSACleanup();return 0;//结束程序运行}printf("已与服务器连接...\n");
步骤5. 链接到服务器(关于IP地址:客户端填写IP地址等也是服务器端的,注意事项参考前文
sockaddr_in serverSockAdd;serverSockAdd.sin_family = AF_INET;serverSockAdd.sin_port = htons(12345); //端口号与服务器程序保持一致serverSockAdd.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");//同上int res = connect(pubServerSock, (struct sockaddr*)&serverSockAdd, sizeof(serverSockAdd));if(SOCKET_ERROR == res){cout << "链接服务器失败,程序即将结束!" << endl;system("pause");closesocket(pubServerSock);WSACleanup();return 0;}
步骤6. 与服务器接收、发送消息。
thread clientThread1(clientRecv); //利用多线程类调用子程序thread clientThread2(clientSend); //利用多线程类调用子程序clientThread1.join();clientThread2.join();
步骤7. 程序结束
closesocket(pubServerSock);WSACleanup();system("pause");return 0;
}
四、子程序实现
1. 收信息子程序
void clientRecv()
{while (true){char buf[1024] = { 0 };int res = recv(pubServerSock, buf, 1024 - 1, 0);if (SOCKET_ERROR == res || 0 == res){cout << "程序运行失败或链接中断!" << endl;closesocket(pubServerSock);WSACleanup();system("pause");exit(0);}else{cout << buf << endl;}}
}
2. 发信息子程序
void clientSend()
{while (true){string buf;cin >> buf;int res = send(pubServerSock, buf.c_str(), strlen(buf.c_str()), 0);if (SOCKET_ERROR == res){cout << "程序运行失败或链接中断。。。" << endl;closesocket(pubServerSock);// closesocket(pubClientSock);WSACleanup();system("pause");exit(0);}}
}
五、运行结果截图