编辑:服务器更新代码
#undef UNICODE
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <thread>
#include <vector>
// Need to link with Ws2_32.lib
#pragma comment (lib, "Ws2_32.lib")
// #pragma comment (lib, "Mswsock.lib")
//Global values
//I put them as global values in order to get the server up and running.
//I will try to pass them as params later on
int iResult;
struct addrinfo *result = NULL;
struct addrinfo hints;
int numClients = 0;
SOCKET ClientSocket[5];
std::thread** sendReceiveThread = new std::thread*[5];
bool firstTime = true;
//Prototypes
int listen(SOCKET ListenSocket);
int accept(SOCKET ListenSocket);
int sendReceive();
int shutdownFunction(SOCKET ClientSocket);
#define DEFAULT_BUFLEN 512
#define DEFAULT_PORT "1016"
int main()
{
std::cout << 1 << std::endl;
WSADATA wsaData;
SOCKET ListenSocket = INVALID_SOCKET;
// Initialize Winsock
std::cout << 2 << std::endl;
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
std::cout << 3 << std::endl;
printf("WSAStartup failed with error: %d\n", iResult);
return 1;
}
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;
listen(ListenSocket);
return 0;
}
int listen(SOCKET ListenSocket)
{
int numPort = 1;
std::vector<std::thread*> thread_vec;
iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);
if (iResult != 0)
{
std::cout << 5 << std::endl;
std::cout << "getaddrinfo failed with error : " << iResult << std::endl;
WSACleanup();
return -1;
}
// Create a SOCKET for connecting to server
std::cout << 6 << std::endl;
ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
if (ListenSocket == INVALID_SOCKET) {
std::cout << 7 << std::endl;
printf("socket failed with error: %ld\n", WSAGetLastError());
freeaddrinfo(result);
WSACleanup();
return -1;
}
char optval = 1;
iResult = ::setsockopt(ListenSocket, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof optval);
if (iResult == SOCKET_ERROR) {
std::cout << 9 << std::endl;
printf("setsockopt failed with error: %d\n", WSAGetLastError());
return -1;
}
// Setup the TCP listening socket
std::cout << 8 << std::endl;
iResult = bind(ListenSocket, result->ai_addr, (int)result->ai_addrlen);
if (iResult == SOCKET_ERROR) {
std::cout << 9 << std::endl;
printf("bind failed with error: %d\n", WSAGetLastError());
freeaddrinfo(result);
closesocket(ListenSocket);
WSACleanup();
return -1;
}
freeaddrinfo(result);
for (int i = 1; i < 5; i++)
{
std::cout << 10 << std::endl;
iResult = listen(ListenSocket, SOMAXCONN);
if (iResult == SOCKET_ERROR) {
std::cout << 11 << std::endl;
printf("listen failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return -1;
}
std::cout << 23 << std::endl;
static std::thread AcceptThread{ [ListenSocket](){accept(ListenSocket); } };
thread_vec.push_back(&AcceptThread);
}
for (auto it : thread_vec) it->join();
return 0;
}
int accept(SOCKET ListenSocket)
{
numClients++;
const int currentNumClients = numClients;
if (firstTime == true)
{
for (int i = 0; i <= 5; i++)
{
ClientSocket[i] = INVALID_SOCKET;
}
firstTime = false;
}
// Accept a client socket
std::cout << 12 << std::endl;
std::cout << 13 << std::endl;
ClientSocket[currentNumClients] = accept(ListenSocket, NULL, NULL);
if (ClientSocket[currentNumClients] == INVALID_SOCKET)
{
printf("accept failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
else{
std::cout << "Client " << currentNumClients << " connected" << std::endl;
}
sendReceiveThread[currentNumClients] = new std::thread([](){sendReceive(); });
(*sendReceiveThread[currentNumClients]).join();
delete sendReceiveThread[currentNumClients];
return 0;
}
int sendReceive()
{
int currentNumClients = numClients;
int iSendResult;
char recvbuf[DEFAULT_BUFLEN];
int recvbuflen = DEFAULT_BUFLEN;
// Receive until the peer shuts down the connection
while(true)
{
std::cout << 14 << std::endl;
iResult = recv(ClientSocket[currentNumClients], recvbuf, recvbuflen, 0);
std::cout << iResult << std::endl;
if (iResult > 0) {
std::cout << 15 << std::endl;
printf("Bytes received: %d\n", iResult);
// Echo the buffer back to the clients
std::cout << 16 << std::endl;
for (int i = 1; i <= numClients; i++)
{
iSendResult = send(ClientSocket[currentNumClients], recvbuf, iResult, 0);
if (iSendResult == SOCKET_ERROR) {
std::cout << 17 << std::endl;
printf("send failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket[currentNumClients]);
WSACleanup();
return 1;
}
printf("Bytes sent: %d\n", iSendResult);
}
}
else if (iResult == 0) {
std::cout << 18 << std::endl;
printf("Connection closing...\n");
break;
}
else {
std::cout << 19 << std::endl;
printf("recv failed with error: %d\n", WSAGetLastError());
std::cout << "On client #" << currentNumClients << std::endl;
break;
}
}
iResult = shutdownFunction(ClientSocket[currentNumClients]);
std::cout << 22 << std::endl;
// cleanup
closesocket(ClientSocket[currentNumClients]);
WSACleanup();
return 0;
}
int shutdownFunction(SOCKET ClientSocket)
{
std::cout << 20 << std::endl;
iResult = shutdown(ClientSocket, SD_SEND);
if (iResult == SOCKET_ERROR) {
std::cout << 21 << std::endl;
printf("shutdown failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}
return 0;
}
我目前正在使用Winsock2在控制台中编写c ++服务器和客户端聊天室。我的问题是,我第二次启动客户端时,似乎连接正常,但服务器似乎没有收到它发送的任何内容。其中一个客户工作正常,另一个工作无效。
这是我的服务器代码:
#undef UNICODE
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <thread>
#include <vector>
// Need to link with Ws2_32.lib
#pragma comment (lib, "Ws2_32.lib")
// #pragma comment (lib, "Mswsock.lib")
//Global values
//I put them as global values in order to get the server up and running.
//I will try to pass them as params later on
int iResult;
struct addrinfo *result = NULL;
struct addrinfo hints;
int numClients = 0;
SOCKET ClientSocket[5];
std::thread** sendReceiveThread = new std::thread*[5];
//Prototypes
int listen(SOCKET ListenSocket);
int accept(SOCKET ListenSocket);
int sendReceive();
int shutdownFunction(SOCKET ClientSocket);
#define DEFAULT_BUFLEN 512
#define DEFAULT_PORT1 "1016"
#define DEFAULT_PORT2 "1017"
#define DEFAULT_PORT3 "1018"
#define DEFAULT_PORT4 "1019"
#define DEFAULT_PORT5 "1020"
int main()
{
std::cout << 1 << std::endl;
WSADATA wsaData;
SOCKET ListenSocket = INVALID_SOCKET;
// Initialize Winsock
std::cout << 2 << std::endl;
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
std::cout << 3 << std::endl;
printf("WSAStartup failed with error: %d\n", iResult);
return 1;
}
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;
listen(ListenSocket);
return 0;
}
int listen(SOCKET ListenSocket)
{
int numPort = 1;
std::vector<std::thread*> thread_vec;
while (true)
{
if (numPort == 1)
{
// Resolve the server address and port
std::cout << 4 << std::endl;
iResult = getaddrinfo(NULL, DEFAULT_PORT1, &hints, &result);
numPort++;
if (iResult != 0) {
std::cout << 5 << std::endl;
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
break;
}
}
else if (numPort == 2)
{
// Resolve the server address and port
std::cout << 4 << std::endl;
iResult = getaddrinfo(NULL, DEFAULT_PORT2, &hints, &result);
numPort++;
if (iResult != 0) {
std::cout << 5 << std::endl;
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
break;
}
}
else if (numPort == 3)
{
// Resolve the server address and port
std::cout << 4 << std::endl;
iResult = getaddrinfo(NULL, DEFAULT_PORT3, &hints, &result);
numPort++;
if (iResult != 0) {
std::cout << 5 << std::endl;
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
break;
}
}
else if (numPort == 4)
{
// Resolve the server address and port
std::cout << 4 << std::endl;
iResult = getaddrinfo(NULL, DEFAULT_PORT4, &hints, &result);
numPort++;
if (iResult != 0) {
std::cout << 5 << std::endl;
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
break;
}
}
else if (numPort == 5)
{
// Resolve the server address and port
std::cout << 4 << std::endl;
iResult = getaddrinfo(NULL, DEFAULT_PORT5, &hints, &result);
numPort++;
if (iResult != 0) {
std::cout << 5 << std::endl;
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
break;
}
}
else if (numPort == 6)
{
break;
}
// Create a SOCKET for connecting to server
std::cout << 6 << std::endl;
ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
if (ListenSocket == INVALID_SOCKET) {
std::cout << 7 << std::endl;
printf("socket failed with error: %ld\n", WSAGetLastError());
freeaddrinfo(result);
WSACleanup();
break;
}
char optval = 1;
iResult = ::setsockopt(ListenSocket, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof optval);
if (iResult == SOCKET_ERROR) {
std::cout << 9 << std::endl;
printf("setsockopt failed with error: %d\n", WSAGetLastError());
}
// Setup the TCP listening socket
std::cout << 8 << std::endl;
iResult = bind(ListenSocket, result->ai_addr, (int)result->ai_addrlen);
if (iResult == SOCKET_ERROR) {
std::cout << 9 << std::endl;
printf("bind failed with error: %d\n", WSAGetLastError());
freeaddrinfo(result);
closesocket(ListenSocket);
WSACleanup();
break;
}
freeaddrinfo(result);
std::cout << 10 << std::endl;
iResult = listen(ListenSocket, SOMAXCONN);
if (iResult == SOCKET_ERROR) {
std::cout << 11 << std::endl;
printf("listen failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
break;
}
std::cout << 23 << std::endl;
static std::thread AcceptThread{ [ListenSocket](){accept(ListenSocket); } };
thread_vec.push_back(&AcceptThread);
}
for (auto it : thread_vec) it->join();
return 0;
}
int accept(SOCKET ListenSocket)
{
numClients++;
const int currentNumClients = numClients;
for (int i = 0; i <= 5; i++)
{
ClientSocket[i] = INVALID_SOCKET;
}
// Accept a client socket
std::cout << 12 << std::endl;
std::cout << 13 << std::endl;
ClientSocket[currentNumClients] = accept(ListenSocket, NULL, NULL);
if (ClientSocket[currentNumClients] == INVALID_SOCKET)
{
printf("accept failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
sendReceiveThread[currentNumClients] = new std::thread([](){sendReceive(); });
(*sendReceiveThread[currentNumClients]).join();
delete sendReceiveThread[currentNumClients];
return 0;
}
int sendReceive()
{
int currentNumClients = numClients;
int iSendResult;
char recvbuf[DEFAULT_BUFLEN];
int recvbuflen = DEFAULT_BUFLEN;
// Receive until the peer shuts down the connection
while(true)
{
std::cout << 14 << std::endl;
iResult = recv(ClientSocket[currentNumClients], recvbuf, recvbuflen, 0);
std::cout << iResult << std::endl;
if (iResult > 0) {
std::cout << 15 << std::endl;
printf("Bytes received: %d\n", iResult);
// Echo the buffer back to the clients
std::cout << 16 << std::endl;
for (int i = 1; i <= numClients; i++)
{
iSendResult = send(ClientSocket[currentNumClients], recvbuf, iResult, 0);
if (iSendResult == SOCKET_ERROR) {
std::cout << 17 << std::endl;
printf("send failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket[currentNumClients]);
WSACleanup();
return 1;
}
printf("Bytes sent: %d\n", iSendResult);
}
}
else if (iResult == 0) {
std::cout << 18 << std::endl;
printf("Connection closing...\n");
break;
}
else {
std::cout << 19 << std::endl;
printf("recv failed with error: %d\n", WSAGetLastError());
std::cout << "On client #" << currentNumClients << std::endl;
break;
}
}
iResult = shutdownFunction(ClientSocket[currentNumClients]);
std::cout << 22 << std::endl;
// cleanup
closesocket(ClientSocket[currentNumClients]);
WSACleanup();
return 0;
}
int shutdownFunction(SOCKET ClientSocket)
{
std::cout << 20 << std::endl;
iResult = shutdown(ClientSocket, SD_SEND);
if (iResult == SOCKET_ERROR) {
std::cout << 21 << std::endl;
printf("shutdown failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}
return 0;
}
这是我的客户代码:
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
#include <string>
#include <iostream>
#include <thread>
// Need to link with Ws2_32.lib, Mswsock.lib, and Advapi32.lib
#pragma comment (lib, "Ws2_32.lib")
#pragma comment (lib, "Mswsock.lib")
#pragma comment (lib, "AdvApi32.lib")
#pragma warning(disable: 4996)
#define DEFAULT_BUFLEN 1024
#define DEFAULT_PORT "1016"
//Prototypes
int sendFunction(char *sendbuf, SOCKET ConnectionSocket);
int shutdownFunction(SOCKET ConnectSocket);
int receiveFunction(SOCKET ConnectSocket, int recvbuflen);
int inputFunction(char *sendbuf, SOCKET ConnectSocket);
int main()
{
std::cout << 1 << std::endl;
WSADATA wsaData;
SOCKET ConnectSocket = INVALID_SOCKET;
struct addrinfo *result = NULL,
*ptr = NULL,
hints;
char *sendbuf = "this is a test";
int iResult;
int recvbuflen = DEFAULT_BUFLEN;
// Initialize Winsock
std::cout << 2 << std::endl;
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed with error: %d\n", iResult);
return 1;
}
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
// Resolve the server address and port
std::cout << 3 << std::endl;
#define IP "127.0.0.1"
iResult = getaddrinfo(IP, DEFAULT_PORT, &hints, &result);
if (iResult != 0) {
std::cout << 4 << std::endl;
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
return 1;
}
// Attempt to connect to an address until one succeeds
for (ptr = result; ptr != NULL; ptr = ptr->ai_next) {
std::cout << 5 << std::endl;
// Create a SOCKET for connecting to server
ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype,
ptr->ai_protocol);
if (ConnectSocket == INVALID_SOCKET) {
std::cout << 6 << std::endl;
printf("socket failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
// Connect to server.
std::cout << 7 << std::endl;
iResult = connect(ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
if (iResult == SOCKET_ERROR) {
closesocket(ConnectSocket);
ConnectSocket = INVALID_SOCKET;
continue;
}
std::cout << 8 << std::endl;
break;
}
freeaddrinfo(result);
//Error management for the ConnectSocket
if (ConnectSocket == INVALID_SOCKET) {
std::cout << 9 << std::endl;
printf("Unable to connect to server!\n");
WSACleanup();
return 1;
}
SOCKET ReceiveSocket = ConnectSocket;
std::thread inputThread{ [sendbuf, ConnectSocket](){inputFunction(sendbuf, ConnectSocket); } };
std::thread receiveThread{ [ReceiveSocket, recvbuflen](){receiveFunction(ReceiveSocket, recvbuflen); } };
inputThread.join();
receiveThread.join();
std::cout << 14 << std::endl;
return 0;
}
int sendFunction(char *sendbuf, SOCKET ConnectionSocket)
{
int iResult;
// Send an initial buffer
std::cout << 10 << std::endl;
if (ConnectionSocket == INVALID_SOCKET)
std::cout << 17 << std::endl;
iResult = send(ConnectionSocket, sendbuf, (int)strlen(sendbuf), 0);
std::cout << 18 << std::endl;
if (iResult == SOCKET_ERROR) {
std::cout << 11 << std::endl;
printf("send failed with error: %d\n", WSAGetLastError());
closesocket(ConnectionSocket);
WSACleanup();
return 1;
}
std::cout << 16 << std::endl;
printf("Bytes Sent: %ld\n", iResult);
return 0;
}
int shutdownFunction(SOCKET ConnectSocket)
{
// shutdown the connection since no more data will be sent
std::cout << 12 << std::endl;
int iResult;
iResult = shutdown(ConnectSocket, SD_SEND);
if (iResult == SOCKET_ERROR) {
printf("shutdown failed with error: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
return 0;
}
int receiveFunction(SOCKET ConnectSocket, int recvbuflen)
{
char *recvContent = new char[recvbuflen];
int iResult;
std::cout << 20 << std::endl;
// Receive until the peer closes the connection
do {
std::cout << 13 << std::endl;
iResult = recv(ConnectSocket, recvContent, recvbuflen, 0);
if (iResult > 0)
{
printf("Bytes received: %d\n", iResult);
for (int i = 0; i < iResult; i++)
{
std::cout << recvContent[i];
}
std::cout << std::endl;
}
else if (iResult == 0)
{
printf("Connection closed\n");
closesocket(ConnectSocket);
WSACleanup();
}
else
{
printf("recv failed with error: %d\n", WSAGetLastError());
shutdownFunction(ConnectSocket);
closesocket(ConnectSocket);
WSACleanup();
}
} while (iResult > 0);
return 0;
}
int inputFunction(char *sendbuf, SOCKET ConnectSocket)
{
std::cout << 15 << std::endl;
std::string temp;
while (true)
{
getline(std::cin, temp);
sendbuf = new char[temp.length() + 1];
strncpy(sendbuf, temp.c_str(), temp.length());
sendbuf[temp.length()] = '\0';
std::thread sendThread{ [sendbuf, ConnectSocket](){sendFunction(sendbuf, ConnectSocket); } };
sendThread.join();
delete[] sendbuf;
}
return 0;
}
作为端口,我使用1016到1020.我已经尝试过更改它们但它没有改变任何东西。作为IP地址,我使用127.0.0.1。 我也不太懂的东西是为什么在我的接受函数中,它不会按照预期的那样打印出12和13。
非常感谢任何帮助,
mindoo