Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > C/C++ Сетевое программирование
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 24.05.2011, 20:23   #1
vaan.sk
Пользователь
 
Аватар для vaan.sk
 
Регистрация: 10.03.2010
Сообщений: 30
По умолчанию Ошибка подключения сервера к клиенту через сокеты

Не подключается клиент к серверу через сокет. При запуске, чистая консоль. Помогите понять проблему (Борланд С++ Билдер)

Сервер
Код:
//---------------------------------------------------------------------------

#include <vcl.h>
#include <iostream.h>
#include <winsock2.h> // Включаем использование сокетов
#pragma comment(lib, "ws2_32.lib") // Используем эту библиотеку

using namespace std;

void main()
{
WSADATA wsa_data; // Информация о сокетах
SOCKET s; // Серверный сокет

s = NULL;

// 1. Инициализируем сокеты (требуем версию 1.1 как минимум)
if (WSAStartup(0x101,&wsa_data) != 0) return;

// 2. Открываем серверный сокет
s = socket(AF_INET, SOCK_STREAM, 0);
if (s == INVALID_SOCKET) return;

int  portik;
cout<<"Server Port: ";
cin>>portik;
// 3. Привязываем сокет к адресу
sockaddr_in addr; // Для хранения адреса
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.S_un.S_addr = INADDR_ANY;
addr.sin_port = htons(portik); // Наш порт, который будем открывать для коннектов
if (bind(s, (LPSOCKADDR)&addr, sizeof(addr)) == SOCKET_ERROR) return;

// 4. Устанавливаем сокет в режим прослушивания
if (listen(s, 1) == SOCKET_ERROR) return;

// 5. Бесконечный цикл получения соединений
while (true)
{
// Принимаем соединения от клиентов
int from_len;
SOCKET client_socket; // Сокет клиента
sockaddr_in client_addr; // Адрес клиента

from_len = sizeof(client_addr);
client_socket = accept(s, (LPSOCKADDR)&client_addr, &from_len);

// Проверяем ошибочность соединения
if (client_socket == INVALID_SOCKET)
continue; // Если что опять переходим в режим ожидания соединения

cout << "Client connected [" << inet_ntoa(client_addr.sin_addr) << "]..." << endl;

// Обмениваемся данными с клиентом.
// Тут должны быть вызовы функций send и recv. Функция recv, если что,
// ждет пока клиент что-нибудь пошлет, send отсылает данные и сразу
// возвращает управление программе

// Отсылаем "приветствие" подключившемуся клиенту
char *greeting = "Welcome to Chat!!!";
send(client_socket, greeting, (int)strlen(greeting),0);

// Получаем ответ клиента
char buf[1024];
int len = recv(client_socket, buf, 1024, 0);
if (len != SOCKET_ERROR)
{
buf[len] = 0; // Не забываем ставить терминирующий ноль (если мы строку принимаем)
cout << buf << endl;
}

// Закрываем сокет
closesocket(client_socket);

// Переходим к следующему клиенту
cout << "...disconnected" << endl;
}

// 6. Закрываем серверный сокет
closesocket(s);

// 7. Завершаем работу с сокетами
WSACleanup();
}
Клиент
Код:
#include <iostream>
#include <vcl>
#include <winsock2.h> // Включаем использование сокетов
#pragma comment(lib, "ws2_32.lib") // Используем эту библиотеку

using namespace std;

void main()
{
WSADATA wsa_data; // Информация о сокетах
SOCKET s; // Серверный сокет

s = NULL;

// 1. Инициализируем сокеты (требуем версию 1.1 как минимум)
if (WSAStartup(0x101,&wsa_data) != 0) return;

// 2. Открываем серверный сокет
s = socket(AF_INET, SOCK_STREAM, 0);
if (s == INVALID_SOCKET) return;

// 3. Привязываем сокет к адресу
sockaddr_in addr; // Для хранения адреса
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
addr.sin_port = htons(7777); // Наш порт, который будем открывать для коннектов
if (bind(s, (LPSOCKADDR)&addr, sizeof(addr)) == SOCKET_ERROR) return;

// 4. Соединяемся
if (connect(s, (LPSOCKADDR)&addr, sizeof(addr)) == SOCKET_ERROR)
return;

// 5. Обмениваемся данными
// (получаем приветствие)
char buf[1024];
int len = recv(s, buf, 1024, 0);
if (len == SOCKET_ERROR) return;

buf[len] = 0;

// Отсылаем ответ серверу
char *reply = "Fuck you too, buddy!";
send(s, reply, (int)strlen(reply), 0);

// 6. Закрываем сокет
closesocket(s);

// 7. Завершаем работу с сокетами
WSACleanup();
}
vaan.sk вне форума Ответить с цитированием
Старый 26.05.2011, 15:37   #2
rpy3uH
добрый няша
Старожил
 
Аватар для rpy3uH
 
Регистрация: 29.10.2006
Сообщений: 4,804
По умолчанию

обрабатывай коды ошибок в программе и выводи их в консоль, сразу станет ясно в чём проблема. Если какая-то функция возвращает SOCKET_ERROR, получай код ошибки через WSAGetLastError и выводи его в консоль
rpy3uH вне форума Ответить с цитированием
Старый 06.08.2013, 11:58   #3
__SOKOL__
Новичок
Джуниор
 
Регистрация: 06.08.2013
Сообщений: 2
По умолчанию

сервер:
когда принимаешься соединения, я думаю тебе незачем выделять память под структуры которыми ты все равно не пользуешься
client_socket = accept(s, (LPSOCKADDR)&client_addr, &from_len);
можно принимать соединения вот так
client_socket = accept(s, 0, 0);

что касается клиента:
на сколько я знаю, то функция bind выпускает в сеть сервер, а ты её используешь зачем-то в клиенте

когда создаешь массив char, то не забывай обнулять:
char buf[1024] = {};
и тебе не потребуется лишняя строчка buf[len] = 0;
__SOKOL__ вне форума Ответить с цитированием
Старый 06.08.2013, 12:02   #4
__SOKOL__
Новичок
Джуниор
 
Регистрация: 06.08.2013
Сообщений: 2
По умолчанию

Мой сервер:
Код:

#include <iostream>
#include <WinSock2.h>
#include <Windows.h>

#pragma comment(lib, "WS2_32.lib")

using namespace std;

DWORD WINAPI Thread_Accept(void *param);
DWORD WINAPI Thread_Recv(void *param);

void main()
{
	try
	{
		WSAData wsaData;
		SOCKET server;

		WSAStartup(MAKEWORD(2, 0), &wsaData);

		server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
		if (server == INVALID_SOCKET) throw "server wasn't initialized";

		int port;
		cout << "Server port: ";
		cin >> port;

		sockaddr_in sa;

		sa.sin_family = AF_INET;
		sa.sin_addr.S_un.S_addr = INADDR_ANY;
		sa.sin_port = htons(port);

		if (bind(server, (LPSOCKADDR)&sa, sizeof(sa)) == SOCKET_ERROR)
			throw "Can't bind";

		if (listen(server, 1) == SOCKET_ERROR)
			throw "Can't listen";

		bool serverOn = true;

		CreateThread(0, 0, Thread_Accept, &server, 0, 0);

		while (true)
		{
			char str[256];
			cin >> str;
			if (strcmp(str, "exit") == 0)
			{
				closesocket(server);
				serverOn = false;
				break;
			}
		}
	}
	catch (char* str)
	{
		cout << str;
	}
	WSACleanup();
	system("pause");
}


DWORD WINAPI Thread_Accept(void *param)
{
	SOCKET *server = (SOCKET*) param;
	while (true)
	{
		SOCKET *client = new SOCKET;
		*client = accept(*server, 0, 0);
		if (*client != INVALID_SOCKET)
		{
			cout << "New connection\n";
			CreateThread(0, 0, Thread_Recv, client, 0, 0);
		}
	}
}


DWORD WINAPI Thread_Recv(void *param)
{
	SOCKET *client = (SOCKET*) param;

	while (*client != INVALID_SOCKET)
	{
		char message[1024] = {};
		if (recv(*client, message, 1024, 0) != SOCKET_ERROR)
		{
			cout << message << endl;
			send(*client, message, strlen(message), 0);
		}
		else
		{
			cout << "client socket error\n";
			break;
		}
	}

	return 0;
}
Мой клиент:
Код:

#include <iostream>
#include <WinSock2.h>
#include <Windows.h>

#pragma comment(lib, "WS2_32.lib")

using namespace std;

DWORD WINAPI Thread_Recv(void* param);

void main()
{
	try
	{
		WSAData wsaData;
		WSAStartup(MAKEWORD(2, 0), &wsaData);
		
		char ip[15] = {};
		cout << "IP: ";
		cin >> ip;

		SOCKET client = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
		if (client == INVALID_SOCKET)
			throw "Invalid socket";

		int port;
		cout << "Port: ";
		cin >> port;
		SOCKADDR_IN sa;
		sa.sin_family = PF_INET;
		sa.sin_port = htons(port);
		sa.sin_addr.S_un.S_addr = inet_addr(ip);

		if (connect(client, (LPSOCKADDR)&sa, sizeof(sa)) == SOCKET_ERROR)
			throw "connect error";

		CreateThread(0, 0, Thread_Recv, &client, 0, 0);

		while (true)
		{
			char command[1024] = {};
			cin >> command;
			if (strcmp(command, "exit") == 0)
				break;
			else
			{
				send(client, command, strlen(command), 0);
			}
		}
	}
	catch (char* str)
	{
		cout << str << endl;
	}
	WSACleanup();

}

DWORD WINAPI Thread_Recv(void* param)
{
	SOCKET *client = (SOCKET*) param;
	while (*client != INVALID_SOCKET)
	{
		char message[1024] = {};
		if (recv(*client, message, 1024, 0) != SOCKET_ERROR)
		{
			cout << "From server: " << message << endl;
		}
	}
	return 0;
}

Последний раз редактировалось __SOKOL__; 06.08.2013 в 12:09.
__SOKOL__ вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Передача файлов через сокеты Joker_vad Работа с сетью в Delphi 1 03.12.2010 12:09
Отправка сообщения с сервера клиенту. securus Работа с сетью в Delphi 0 31.08.2010 03:32
прием передача сообщения от сервера клиенту и на оборот Lokos Работа с сетью в Delphi 4 24.08.2010 18:24
как построить обратную связь от сервера клиенту. язык Delphi компонент IdTCPClient S_Yevgeniy Работа с сетью в Delphi 6 10.12.2009 11:13
Проблема с отправкой MemoryStream от сервера к клиенту Ragnarek Работа с сетью в Delphi 4 07.02.2009 10:29