������� Process Explorer, ����� ��� �������� 1� (� ��� ����� ���������) � ����� ��.
������� �� ��������� �������:
1. ����������� ��������� �������� ������. �� ��������� �� 5000, ����� ���������� �� 65536.
HKLMSYSTEMCurrentControlSetServicesTcpipParametersMaxUserPort
2. ����� ��������� ����� ���������� ���������� � ��������� �������� � 4 ����� �� 30 ������.
HKLMSystemCurrentControlSetServicesTcpipParametersTCPTimedWaitDelay 3. ������� ���� (���������, �������� � ��.) ���������� ����� 1� �������, ������������ ������� ��������, � ��� ������� ��� ������ ��� ��������. ���� � ���������� - ����� ����������! :)
I started with the simple server tutorial on the msdn website in order to learn how to use sockets in client and server applications.
Once I was done following thet tutorial, I started adapting the client and server code into multithreaded proggrams in order to make a tchat client and server. Everything was going very well until I ran into WSA error 10048. I tried using different ports for each socket but it still did not solve the error.
Here is my server code :
#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: %dn", 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;
std::thread ListenThread{ [ListenSocket](){listen(ListenSocket); } };
ListenThread.join();
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: %dn", 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: %dn", 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: %dn", 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: %dn", 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: %dn", iResult);
WSACleanup();
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: %ldn", WSAGetLastError());
freeaddrinfo(result);
WSACleanup();
break;
}
// 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: %dn", 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: %dn", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
break;
}
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: %dn", 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: %dn", 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: %dn", WSAGetLastError());
closesocket(ClientSocket[currentNumClients]);
WSACleanup();
return 1;
}
printf("Bytes sent: %dn", 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: %dn", 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: %dn", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}
return 0;
}
You might notice the different couts, those are just couts to know how the proggram behaves.
I have a stress test application which spawns 100 threads and then communicates through TCP to a server on the same machine.
The connection code looks like:
bool CSockConnector::Connect(const CInetAddr &Addr, CSockStream &Socket)
{
Socket.SetSocket(socket(AF_INET, SOCK_STREAM, 0));
if (Socket.GetSocket() == INVALID_SOCKET)
{
// printf(«Cannot create socket: %dn», WSAGetLastError());
return false;
}
if (connect(Socket.GetSocket(), Addr.GetAddr(), Addr.GetSize()) != 0)
{
printf(«Connection error: %dn», WSAGetLastError());
return false;
}
return true;
}
As one can see the code is pretty clean. However I have the problem that some times under alot of pressure I get a WSA error 10048. Looking it up seems to be a bind problem.
Interesting observations are that I have never seen this error with VC 2005 but only VCNET 2003.
On the server side I do use REUSE_ADDR for the listen socket but it should not matter.
What could the idea behind this error be? As the manual says connect() should find a new port number to work on.
Is 100 clients too much to handle? I don’t believe that would be the case.
Thanks.
— Henrik
0 / 0 / 0 Регистрация: 24.01.2013 Сообщений: 12 |
|
1 |
|
25.02.2017, 16:30. Показов 8171. Ответов 8
Подскажите, при запуске программы выскакивает окно — windows socket error: обычно разрешается только одно использование адреса сокета (протокол/сетевой адрес/порт) (10048), on API ‘buld’ и еще одно — Acces violation at address 00502CCF in module ‘HASyn.exe’. Write of address 0FA5C000.
0 |
4237 / 1739 / 247 Регистрация: 01.05.2013 Сообщений: 7,739 |
|
25.02.2017, 18:18 |
2 |
anton877, Windows sockets error codes, values, and meanings. WSAEADDRINUSE (10048) Перевод: адрес уже используется. Посмотрите. Будет ли наблюдаться эта ошибка при запуске программы в Безопасном режиме с загрузкой сетевых драйверов ?
0 |
0 / 0 / 0 Регистрация: 24.01.2013 Сообщений: 12 |
|
25.02.2017, 18:30 [ТС] |
3 |
в безопасном режиме тоже самое.
0 |
4237 / 1739 / 247 Регистрация: 01.05.2013 Сообщений: 7,739 |
|
25.02.2017, 18:48 |
4 |
anton877, Хм… то что в безопасном выскакивает эта ошибка — странно. Далее действуйте методом «половинного деления». Включите половину служб и снова перезагрузитесь. Если проблема не появляется, причина в оставшихся отключенных службах. Если проблема воспроизводится, причина во включенных службах — отключите половину из них и снова перезагрузитесь. Действуя таким образом, вы сможете выявить службу, являющуюся причиной проблемы, и определить программу, которой она принадлежит. Далее можно порекомендовать лишь обновление программы до последней версии или ее удаление. 2. Запустить командную строку от имени администратора и ввести команду Посмотрите нет ли в списке процессов (PID),которые используют один и тот же IP-адрес. Далее запустите диспетчер задач — > вкладка Процессы -> Вид -> Выбрать столбцы -> отметьте ИД процесса и нажмите ОК -> далее с помощью номера PID вы найдёте процессы,кторые используют одни и те же IP-адреса.
0 |
0 / 0 / 0 Регистрация: 24.01.2013 Сообщений: 12 |
|
25.02.2017, 20:20 [ТС] |
5 |
сейчас попробую. Добавлено через 7 минут процесс еще идет Добавлено через 14 минут одинаковых не заметил, может не там смотрю?
0 |
4237 / 1739 / 247 Регистрация: 01.05.2013 Сообщений: 7,739 |
|
25.02.2017, 22:54 |
6 |
anton877, список активных адресов может быть огромен и не уместится в командной строке. Лучше используйте команду Код netstat -aon >C:result.log .
0 |
0 / 0 / 0 Регистрация: 24.01.2013 Сообщений: 12 |
|
26.02.2017, 02:26 [ТС] |
7 |
при вводе C:result.log. все резко обрывается и я ничего не вижу, окна с процессом работы не вижу. в ИД процесса, я не заметил одинаковых совпадений, или нужно не одинаковые искать?
0 |
4237 / 1739 / 247 Регистрация: 01.05.2013 Сообщений: 7,739 |
|
26.02.2017, 02:28 |
8 |
anton877, так и должно быть. Весь результат выполнения команды записывается в файл result.log.
0 |
0 / 0 / 0 Регистрация: 24.01.2013 Сообщений: 12 |
|
26.02.2017, 15:25 [ТС] |
9 |
я у себя не нахожу этого файла result.log
0 |