服务器:
#include <winsock2.h>
#include <iostream>
#pragma comment(lib, "WS2_32")
//#include<stdio.h>
using namespace std;
int main()
{
//1.启动SOCKET库,版本为2.0
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD(2, 0);
err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0)
{
cout << "Socket2.0初始化失败,Exit!";
return 0;
}
if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 0)
{
WSACleanup();
return 0;
}
//2.创建套接字,用于监听
SOCKET sock;
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock == INVALID_SOCKET)
{
cout << "Socket 创建失败,Exit!";
return 0;
}
//3.绑定
SOCKADDR_IN myaddr; //sockaddr_in相当于sockaddr结构
memset(&myaddr, 0, sizeof(myaddr));//初始化 清零
myaddr.sin_family = AF_INET;//只能为这个值
myaddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);//将u_long型转换为网络字节序列
myaddr.sin_port = htons(7861);// 将u_short型转换为网络字节序列
bind(sock, (SOCKADDR*)&myaddr, sizeof(myaddr));//绑定套接字
//4.设置监听
listen(sock, 5);
//5.等待并接受数据
SOCKADDR_IN addrClient;
int len = sizeof(SOCKADDR);
//char buf[256] = "";
int number = 0;
while (true) {
SOCKET sockConnect = accept(sock, (SOCKADDR*)&addrClient, &len);
cout << "与IP地址:" << inet_ntoa(addrClient.sin_addr) << "建立连接。" << endl;
while (true) {
char sendBuf[100];
sprintf(sendBuf, "欢迎%s%s%d!!", inet_ntoa(addrClient.sin_addr), "客户端", ++number);
//发送
//send(sockConnect, sendBuf, strlen(sendBuf) + 1, 0);
if (send(sockConnect, sendBuf, strlen(sendBuf) + 1, 0) == SOCKET_ERROR) {
cout << "发送失败,可能是客户端已关闭" << endl;
break;
}
//接收
char recvBuf[100];
if (recv(sockConnect, recvBuf, 100, 0) == -1)//TCP CLIENT端关闭后,服务器端的recv会一直返回-1,此时如果不退出,服务端recv会一直接收
{
cout << "接收失败,可能是客户端已关闭" << endl;
break;
}
else {
cout << "IP地址:" << inet_ntoa(addrClient.sin_addr) << "的客户端发来消息:";
cout << recvBuf << endl;
//printf("%s\n", recvBuf);
}
memset(recvBuf,0, sizeof(recvBuf));//把接收的数据清空
Sleep(2000);
}
closesocket(sockConnect);
}
//??这两个条件?
//if (!closesocket(sock))
//{
// WSAGetLastError();
// return 0;
//}
//if (!WSACleanup())
//{
// WSAGetLastError();
// return 0;
//}
cout << "服务器关闭" << endl;
closesocket(sock);
WSACleanup();
return 0;
}
客户端:
#include <winsock2.h>
#pragma comment(lib, "WS2_32")
#include <iostream>
using namespace std;
int main()
{
//1.启动SOCKET库,版本为2.0
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD(2, 0);
err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0)
{
cout << "Socket2.0初始化失败,Exit!";
return 0;
}
if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 0)
{
WSACleanup();
return 0;
}
//2.创建socket,
SOCKET sock; //socket
sock = socket(
AF_INET, //internetwork: UDP, TCP, etc
SOCK_STREAM, //TCP
0 //protocol
);
if (sock == INVALID_SOCKET) {
cout << "Socket 创建失败,Exit!";
return 0;
}
//3.设置发往的地址
SOCKADDR_IN addrto; //发往的地址
memset(&addrto, 0, sizeof(addrto));
addrto.sin_family = AF_INET;
// https://jingyan.baidu.com/article/1709ad8041dca64634c4f006.html
//去掉SDL检查。设置项目属性,将c/c++->SDL检查设置为“否”即可跳过检查,使用旧的函数可编译成功。
addrto.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); //旧函数,不设置sdl检查会报错
//端口号必须和服务器绑定的端口号一致
addrto.sin_port = htons(7861);
//申请链接服务器
connect(sock, (SOCKADDR*)&addrto, sizeof(SOCKADDR));
int n=0;
while (true) {
char recvBuf[100];
recv(sock, recvBuf, 100, 0);
cout << recvBuf << endl;
char sendBuf[100];
sprintf(sendBuf, "你好,我是客户端%d", ++n);
send(sock, sendBuf, 100, 0);
Sleep(1000);
if (n > 10)break;
}
Sleep(5000);
//if (!closesocket(sock))
//{
// WSAGetLastError();
// return 0;
//}
//if (!WSACleanup())
//{
// WSAGetLastError();
// return 0;
//}
cout << "客户端关闭" << endl;
closesocket(sock);
WSACleanup();
return 0;
}
运行结果:
启动了两次客户端,两次均正常连接