C++ socket实例,真正的聊天室
2019-03-16
摘抄自:https://blog.csdn.net/qq_39638957/article/details/80631422 修复部分BUG和没用代码,同时完善了服务器只能返回你好!服务端的不足
编译器环境:Visual Studio 2013
服务端代码:
#include <winsock2.h> #include<stdio.h> #include<iostream> #include<string> using namespace std; #pragma comment(lib,"ws2_32.lib")//链接这个库 //TCP服务器端 int main() { //调用winsock WORD sockVersion = MAKEWORD(2, 2);//请求使用的winsock版本 WSADATA wsaData; // 实际返回的winsock版本 if (WSAStartup(sockVersion, &wsaData) != 0){ return 0; } //创建socket SOCKET slisten = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);//参数分别为协议族,类型,协议号 AF_INET代表TCP/IP if (slisten == INVALID_SOCKET){//异常处理 printf("scoket error!"); return 0; } //bind sockaddr_in sin; //服务器端点地址 sin.sin_family = AF_INET; //协议族 sin.sin_port = htons(8888); //端口号, htons函数将本地字节顺序变为网络字节顺序(16位) sin.sin_addr.S_un.S_addr = INADDR_ANY;//服务器bind时需要使用地址通配 if (bind(slisten, (LPSOCKADDR)&sin, sizeof(sin)) == SOCKET_ERROR){ //LPSOCKADDR是类型强制转换 printf("bind error !"); } //listen if (listen(slisten, 5) == SOCKET_ERROR){ //5为queuesize,缓存区大小 printf("listen error !"); return 0; } //由于使用的是TCP ,socket stream,要循环接收数据 SOCKET sClient;//声明变量 sockaddr_in remoteAddr; int nAddrlen = sizeof(remoteAddr); char revData[255];//buffer while (true) { printf("等待连接...\n"); sClient = accept(slisten, (SOCKADDR *)&remoteAddr, &nAddrlen);//accept会新建一个socket if (sClient == INVALID_SOCKET){ printf("accept error !"); continue;//重新开始循环 } printf("接收到一个连接: %s \r\n", inet_ntoa(remoteAddr.sin_addr)); //inet将ip地址结构转成字符串 , \r是回车 //接收数据 int ret = recv(sClient, revData, 255, 0); if (ret>0){ revData[ret] = 0x00; printf("来自用户端发来的数据:"); printf(revData); printf("\n"); } //发送数据 printf("请输入返回给客户端的数据:"); string data; cin >> data;//键盘读入数据 const char* sendData; sendData = data.c_str(); //string变为const char* send(sClient, sendData, strlen(sendData), 0); closesocket(sClient); } closesocket(slisten); WSACleanup(); return 0; }
客户端代码:
#include<WINSOCK2.H> #include<STDIO.H> #include<iostream> #include<cstring> #include<string> using namespace std; #pragma comment(lib,"ws2_32.lib")//链接这个库 //TCP客户端 int main(){ WORD sockVersion = MAKEWORD(2, 2); WSADATA data; if (WSAStartup(sockVersion, &data) != 0){ return 0; } printf("连击成功\n请输入你要发给服务器的数据:"); while (true){ SOCKET sclient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (sclient == INVALID_SOCKET){ printf("invalid socket!"); return 0; } sockaddr_in serAddr; //要连接的服务器端 的 端点地址 serAddr.sin_family = AF_INET; serAddr.sin_port = htons(8888); serAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); //将ip变为地址结构 //客户端程序不需要bind本机端点地址,系统会自动完成 if (connect(sclient, (sockaddr*)&serAddr, sizeof(serAddr)) == SOCKET_ERROR){ printf("connect error !"); closesocket(sclient); return 0; } string data; cin >> data;//键盘读入数据 const char* sendData; sendData = data.c_str(); //string变为const char* send(sclient, sendData, strlen(sendData), 0); char recData[255]; int ret = recv(sclient, recData, 255, 0); if (ret>0){ recData[ret] = 0x00; printf("来自服务器返回的数据:"); printf(recData); printf("\n请输入你要发给服务器的数据:"); } closesocket(sclient); } WSACleanup(); return 0; }
发表评论: