服务端
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#include <WinSock2.h>
#include <WS2tcpip.h>
#pragma comment(lib,"ws2_32.lib")
#include <stdio.h>
#include <Windows.h>
#include <conio.h>
#include <map>
#include <algorithm>
#include <string>
#include <vector>
#include <iostream>
using std::string;
using std::map;
using std::vector;
map<USHORT, SOCKET> socketMap;
//发送数据
void WINAPI SendMsg()
{
while (1)
{
// '+' 43
// '/' 47
// '*' 42
int key = _getch();
if (key == 43) //发送消息
{
printf("【*】群发【/】单发\n");
key = _getch();
printf("发送内容:");
char sendStr[100] = {};
gets_s(sendStr, sizeof(sendStr));
//scanf("%s",sendStr);
int sendRet = 0;
if(key == 42 ) //群发
{
for (auto inter = socketMap.begin(); inter != socketMap.end(); ++inter)
{
SOCKET clientSocket = inter->second;
sendRet = send(clientSocket, sendStr, strlen(sendStr), 0);
}
}
else if(key == 47) //单发
{
printf("客户端端口号:");
int hostPort = 0;
//scanf("%d",&port);
char temp[100] = {};
gets_s((char*)&temp, sizeof(temp));
sscanf(temp, "%d", &hostPort);
if (socketMap.find(hostPort) != socketMap.end())
{
SOCKET clientSocket = socketMap.at(hostPort);
sendRet = send(clientSocket, sendStr, strlen(sendStr), 0);
}
else
{
printf("输入端口号有误\n");
continue;
}
}
if(sendRet != 0)
printf("已发送\n");
else
printf("发送失败\n");
}
}
}
//接收客户端数据
DWORD WINAPI RecvMsg(SOCKET* clientSocket)
{
//int threadId = GetCurrentThreadId();
//int n = 5;
while (1)
{
char recvStr[10000] = {};
int recvRet = recv(*clientSocket, recvStr, sizeof(recvStr), 0);
if (recvRet != -1 && recvRet != 0)
printf("thread【%d】:%s\n=========\n", (int)GetCurrentThreadId(), recvStr);
else
{
auto retVal = std::find_if(socketMap.begin(), socketMap.end(), [clientSocket](map<USHORT, SOCKET>::value_type val)
{
return val.second == *clientSocket;
});
if (retVal != socketMap.end())
{
printf("客户端%d已断开\n", retVal->first);
closesocket(retVal->second);
socketMap.erase(retVal);
break;
}
else
{
printf("没有该客户端\n");
}
}
}
return 0;
}
int main()
{
CreateThread(0, 0, (LPTHREAD_START_ROUTINE)SendMsg, 0, 0, 0);
WSADATA wsaData = { 0 };
WSAStartup(MAKEWORD(2,2),&wsaData);
SOCKET serverSocket = socket(AF_INET,SOCK_STREAM,0);
sockaddr_in sockaddr;
sockaddr.sin_family = AF_INET;
sockaddr.sin_addr.S_un.S_addr = INADDR_ANY; //监听本机任意IP地址的8888端口
//sockaddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
sockaddr.sin_port = htons(8888);
int bindRet = bind(serverSocket, (SOCKADDR*)&sockaddr, sizeof(sockaddr));
if (bindRet == SOCKET_ERROR)
{
printf("绑定失败\n");
closesocket(serverSocket);
WSACleanup();
getchar();
exit(0);
}
int listenRet = listen(serverSocket, 3);
if (listenRet == -1)
{
printf("监听失败\n");
closesocket(serverSocket);
WSACleanup();
system("pause");
return 0;
}
printf("监听中...\n");
while (1)
{
SOCKADDR_IN clientSockAddr_in = {};
int len = sizeof(clientSockAddr_in);
SOCKET clientSocket = accept(serverSocket, (SOCKADDR*)&clientSockAddr_in, &len);
printf("有客户端连接\n");
printf("ip=%s,port=%d\n", inet_ntoa(clientSockAddr_in.sin_addr), ntohs(clientSockAddr_in.sin_port));
socketMap[ntohs(clientSockAddr_in.sin_port)] = clientSocket;
CreateThread(0, 0, (LPTHREAD_START_ROUTINE)RecvMsg, &socketMap[ntohs(clientSockAddr_in.sin_port)], 0, 0);
}
}
客户端
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#include <WinSock2.h>
#include <WS2tcpip.h>
#pragma comment(lib,"ws2_32.lib")
#include <stdio.h>
#include <iostream>
DWORD WINAPI RecvMsg(const SOCKET* clientSocket)
{
while (1)
{
char recvStr[100] = {};
int recvRet = recv(*clientSocket, recvStr, sizeof(recvStr), 0);
if (recvRet != -1)
printf("服务器说:%s\n", recvStr);
else
{
printf("服务器已断开\n");
closesocket(*clientSocket);
WSACleanup();
system("pause");
closesocket(*clientSocket);
WSACleanup();
exit(0);
}
}
return 0;
}
int main()
{
WSADATA wsaData = { 0 };
WSAStartup(MAKEWORD(2, 2), &wsaData);
SOCKET clientSocket = socket(AF_INET, SOCK_STREAM, 0);
//******bind自定义端口号测试*********/
SOCKADDR_IN clientSockAddr_in = { 0 };
clientSockAddr_in.sin_family = AF_INET;
clientSockAddr_in.sin_addr.S_un.S_addr = INADDR_ANY; //本机IP
clientSockAddr_in.sin_port = htons(2222);
if(bind(clientSocket, (SOCKADDR*)&clientSockAddr_in, sizeof(clientSockAddr_in)) == SOCKET_ERROR)
{
std::cout << "绑定套接字失败\n";
closesocket(clientSocket);
WSACleanup();
system("pause");
return 0;
}
/***************************************/
SOCKADDR_IN sockaddr_in;
sockaddr_in.sin_family = AF_INET;
sockaddr_in.sin_addr.S_un.S_addr = inet_addr("172.16.20.203"); //inet_addr("192.168.18.173"); //服务端ip地址
//sockaddr_in.sin_addr.S_un.S_addr = inet_addr("192.168.74.128");
sockaddr_in.sin_port = htons(8888); //服务端监听的端口
int conRet = connect(clientSocket,(SOCKADDR*)&sockaddr_in, sizeof(sockaddr_in));
if (conRet != SOCKET_ERROR)
{
printf("连接成功\n");
CreateThread(0, 0, (LPTHREAD_START_ROUTINE)RecvMsg, &clientSocket, 0, 0);
}
else
{
printf("连接失败,返回%d\n", conRet);
closesocket(clientSocket);
WSACleanup();
}
while (1)
{
printf("输入内容\n");
char sendStr[10000] = {};
//scanf("%s", sendStr); //遇到空格会截断后面内容
gets_s(sendStr, sizeof(sendStr));
int ret = send(clientSocket, sendStr, strlen(sendStr), 0);
if (ret != 0)
printf("客户端发送数据%dbyte\n", ret);
}
}