参考了博文并进行了修改及注释``https://www.youkuaiyun.com/gather_28/MtzaAg4sMDctYmxvZwO0O0OO0O0O.html
不知道为什么inet_addr()函数用起来会出现错误所以需要简单修改一下设置:项目>属性>配置属性>C/C++>所有选项>SDL检查设置为否可通过编译。
程序中备注非常详细,不再累述直接贴代码。
server.cpp
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include<iostream>
#include<string>
#include<cstring>
#include<WS2tcpip.h>
#include <WinSock2.h> //一般情况下,这个头文件位于windows.h之前,避免发生某些错误
#include<Windows.h>
#pragma comment(lib, "ws2_32.lib") //显示加载 ws2_32.dll ws2_32.dll就是最新socket版本啦
using namespace std;
int main()
{
cout << "-----------服务器-----------" << endl;
// 1 初始化 DLL
WSADATA wsadata;
WSAStartup(MAKEWORD(2, 2), &wsadata);
// 2 创建服务器的套接字
SOCKET serviceSocket;
serviceSocket = socket(AF_INET, SOCK_STREAM, 0);
if (SOCKET_ERROR == serviceSocket) {cout << "套接字闯创建失败!" << endl;}
else {cout << "套接字创建成功!" << endl;}
// 3 绑定套接字 指定绑定的IP地址和端口号
sockaddr_in socketAddr; //一个绑定地址:有IP地址,有端口号,有协议族
socketAddr.sin_family = AF_INET; // internetwork: UDP, TCP, etc.
socketAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); //127.开头的都是本地
socketAddr.sin_port = htons(1234); //端口号用函数转变类型
int bRes = bind(serviceSocket, (SOCKADDR*)&socketAddr, sizeof(SOCKADDR));
if (SOCKET_ERROR == bRes) {cout << "绑定失败!" << endl;}
else {cout << "绑定成功!" << endl;}
// 4 服务器监听
int lLen = listen(serviceSocket, 5); //监听的第二个参数就是:能存放多少个客户端请求,到并发编程的时候很有用
if (SOCKET_ERROR == lLen) {cout << "监听失败!" << endl;}
else {cout << "监听成功!" << endl;}
// 5 接受请求
sockaddr_in revClientAddr;
SOCKET recvClientSocket = INVALID_SOCKET; //初始化一个接受的客户端socket
int _revSize = sizeof(sockaddr_in);
recvClientSocket = accept(serviceSocket, (SOCKADDR*)&revClientAddr, &_revSize);
if (INVALID_SOCKET == recvClientSocket) {cout << "服务端接受请求失败!" << endl;}
else {cout << "服务端接受请求成功!" << endl;}
// 6 循环发送/接受 数据
while (true) {
char recvBuf[1024] = {};
int reLen = recv(recvClientSocket, recvBuf, 1024, 0); //阻塞函数,等待接收数据
if (SOCKET_ERROR == reLen) {
cout << "服务端发送数据失败" << endl;
}
else {
cout << "客户端请求命令:" << recvBuf << endl;
if (0 == strcmp("cls", recvBuf)) {
system(recvBuf);//服务端执行命令 ,清空服务器窗口命令
}
else if (0 == strcmp("获取版本信息", recvBuf)) {
string verData = "Version: 1.0.1\nAuthor: Primer\nReleaseData: 2019-04-21";//返回数据
int sLen = send(recvClientSocket, (char*)verData.c_str(), verData.length(), 0);
}
else if (0 == strcmp("exit", recvBuf)) {
string verData = "Client request to exit.";//返回数据
int sLen = send(recvClientSocket, (char*)verData.c_str(), verData.length(), 0);
cout << endl << "退出服务器" << endl;
break;
}
else {
cout << "\t不正确..." << endl;
}
cout << endl;
}
}
// 7 关闭socket
closesocket(recvClientSocket);
closesocket(serviceSocket);
// 8 终止
WSACleanup();
cout << "服务器停止" << endl;
cin.get();
return 0;
}
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include<iostream>
#include<string>
#include<cstring>
#include<WS2tcpip.h>
#include <WinSock2.h>
#include<Windows.h>
#pragma comment(lib, "ws2_32.lib") //加载 ws2_32.dll
using namespace std;
int main()
{
cout << "-----------客户端-----------" << endl;
// 1 初始化
WSADATA wsadata;
WSAStartup(MAKEWORD(2, 2), &wsadata);
// 2 创建套接字
SOCKET clientSocket = {};
clientSocket = socket(PF_INET, SOCK_STREAM, 0);
if (SOCKET_ERROR == clientSocket) { cout << "套接字闯创建失败!" << endl; }
else { cout << "套接字创建成功!" << endl; }
// 3 绑定套接字 指定绑定的IP地址和端口号
sockaddr_in socketAddr;
socketAddr.sin_family = PF_INET;
socketAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
socketAddr.sin_port = htons(1234);
int cRes = connect(clientSocket, (SOCKADDR*)&socketAddr, sizeof(SOCKADDR));
if (SOCKET_ERROR == cRes) { cout << "客户端:\t\t与服务器连接失败....." << endl; }
else { cout << "客户端:\t\t与服务器连接成功....." << endl; }
while (true) {
string s;
cout << "请输入发送数据:";
getline(cin, s); //可输入空格,默认以换行符结束输入,
// 4 发送请求
send(clientSocket, (char*)s.c_str(), s.length(), 0);
// 5 发送/接受 数据
if (0 == strcmp("获取版本信息", s.c_str())) {
char recvBuf[4024] = {};
int reLen = recv(clientSocket, recvBuf, 4024, 0);//阻塞函数,等待接受数据
cout << endl << recvBuf << endl << endl;
}
if (0 == strcmp("exit", s.c_str())) {
char recvBuf[4024] = {};
int reLen = recv(clientSocket, recvBuf, 4024, 0);//阻塞函数,等待接受数据
cout << endl << recvBuf << endl << endl;
break;
}
}
// 6 关闭socket
closesocket(clientSocket);
// 7 终止
WSACleanup();
cout << "客户端退出" << endl;
cin.get();
return 0;
}
在visual studio中生成对应两个server.exe和client.exe,进入项目文件夹的debug中找到对应两个.exe,先运行server.exe再运行client.exe即可