![]() |
Здравствуйте, гость ( Вход | Регистрация )
![]() ![]() |
![]() |
![]()
Сообщение
#81
|
|
![]() 😸🧡✊✌️ Сообщений: 16 397 Спасибо сказали: 3234 раза ![]() |
The class describes a stream buffer that controls the transmission of elements to and from a sequence of elements stored in a char array object. Depending on how it is constructed, the object can be allocated, extended, and freed as necessary to accommodate changes in the sequence.
-------------------- Я слежу за тобой!
![]() ![]() Цитата Всегда приятно осознавать, что кто-то делает что-то хуже, чем делал бы ты, если бы умел. Борис "Бонус" Репетур, "От винта!", выпуск 38. |
|
|
![]()
Сообщение
#82
|
|
VCMI developer Сообщений: 377 Спасибо сказали: 690 раз ![]() |
Единственное что сейчас эта штука называется std::stringstream а не strstream, а так да, оно:
Код #include <sstream> #include <iostream> int main() { char * data = new char[1024]; // данные, которые НЕ будут удалены потоком for (size_t i=0; i< 1024; i++) data[i] = rand() % 26 + 'a'; // заполняем случайными буковками std::ostringstream buffer; buffer.rdbuf()->pubsetbuf(data, 1024); // собственно установка наших данных std::cout << buffer.str(); // проверка delete [] data; // не забываем удалить данные } EDIT: считал что stringstream и прочие удалят этот буфер - оказывается что нет. -------------------- Слава Україні!
|
|
|
![]()
Сообщение
#83
|
|
![]() Зануда Сообщений: 2 237 Спасибо сказали: 2894 раза ![]() |
А еще можно написать перед вызовом main-функции "using namespace std;" и не париться с прописыванием везде "std::", вот так:
Код #include <sstream>
#include <iostream> using namespace std; int main() ... |
|
|
![]()
Сообщение
#84
|
|
VCMI developer Сообщений: 377 Спасибо сказали: 690 раз ![]() |
Спорный вопрос.
Файл 1 Код using namespace std; using namespace boost; // а что? популярная библиотечка И получаем абсолютно бессмысленную ругань от компилятора, если используем что-то что есть и там, и там (а такого более, чем достаточно) Файл 2 Код using namespace boost; using namespace std; // вполне возможно что переставили их местами или хедеры в другом порядке подключены А это вместе с первым даст еще и приколы при линковке Или такое: Код class foo { int max; void bar(); }; void foo::bar(vector<int> data) { int count; // специально назвали так, чтоб не конфликтовать с std::max for (size_t i=0; i<data.size(); i++) count = max(data[i], count); } Забыли что где-то max уже объявлена, а count тоже в std есть. Сидим и офигеваем от выдачи компилятора. В std еще много неплохих имен. Например написали функцию distance(const Point* a, const Point* - расстояние между двумя точками. А вызывается std::distance - расстояние между указателями. А еще там есть count, equal, unique, map. Список можно продолжать. Префикс (в случае с C) или пространство имен (C++) это легкий способ выяснить откуда какая функция просто глянув на имя - неплохой бонус для читаемости кода. И меньше шансов отхватить от компилятора. -------------------- Слава Україні!
|
|
|
![]()
Сообщение
#85
|
|
![]() Immortal Сообщений: 1 437 Спасибо сказали: 2149 раз ![]() |
|
|
|
![]()
Сообщение
#86
|
|
![]() Летсплеер Сообщений: 2 273 Спасибо сказали: 1844 раза ![]() |
Ребят, такая просьба. У моего друга - проблема с С++ (он не из моего города). Сам я только Pascal проходил. А помочь другу все-таки хочется. Поможете составить программу по такой вот задачке?
Цитата Дан двумерный целочисленный массив. Если в массиве нет элементов, делящихся на 3 без остатка, сформировать новый одномерный массив из положительных элементов двумерного массива.
-------------------- Канал на YouTube - http://youtube.com/user/Septimus1993
Форум - http://septimus.5nx.ru Группа ВКонтакте - http://vk.com/septimus1993 |
|
|
![]()
Сообщение
#87
|
|
![]() Яблочный произвол! Сообщений: 11 080 Спасибо сказали: 3988 раз ![]() |
друг зря взялся за это программирование
|
|
|
![]()
Сообщение
#88
|
|
![]() Etoslozhnostatus Сообщений: 8 573 Спасибо сказали: 15949 раз ![]() |
Код #define N 100
#define M 100 int arrin[N][M]; int arrout[N*M]; //int *arrout; void func() { int x, y, z; int is3div = 1; for(x = 0; x < N && is3div; x++)// если находим элемент, делящийся на 3 без остатка, то дальше нет смысла считать for(y = 0; y < M && is3div; y++) is3div &= arrin[y][x]%3;//если есть элемент, делящийся на 3 без остатка, то обнуляем z = 0;// число элементов в новом одномерном списке if(is3div) for( x = 0, z = 0; x < N; x++) for( y = 0; y < M; y++) if(arrin[y][x] > 0){ arrout[z] = arrin[y][x]; z++; } } -------------------- - Да ну!?
- Horn of the Argali гну! |
|
|
![]()
Сообщение
#89
|
|
![]() Разработчик Сообщений: 534 Спасибо сказали: 222 раза ![]() |
Уже собираюсь в школу, и вот подумал для одноклассников сделать урок программирования, который учит делать 2 самые простые программки: "Привет всем!" и "Калькулятор":
Урок 1 Программа Привет всем! В терминале создаёте файл командой Код nano hello.cc В редакторе вставляете следующий код Код // программа 'Hello World!' #include <iostream> int main() { std::cout << "Привет всем, это Даня! \n"; return 0; } Сохраняетесь (ctrl+o). Потом в терминале даете следующую команду: Код g++ hello.cc -o hello Потом запускаете программу командой Код ./hello Урок 2 программа калькулятор В терминале создаёте файл командой Код nano kakul.cc В редакторе вставляете следующий код Код #include <stdio.h> int main(void) { float num1; float num2; char op; printf("Первое число: "); scanf("%f",&num1); printf("Второе число: "); scanf("%f",&num2); printf("Оператор ( + - * / ): "); while ((op = getchar()) != EOF) { if (op == '+') { printf("%6.2f\n",num1 + num2); break; } else if(op == '-') { printf("%6.2f\n",num1 - num2); break; } else if(op == '*') { printf("%6.2f\n",num1 * num2); break; } else if(op == '/') { if(num2 == 0) { printf("Ошибка: деление на ноль!\n"); break; } else { printf("%6.2f\n",num1 / num2); break; } } } return 0; } Сохраняетесь (ctrl+o). Потом в терминале даете следующую команду: Код g++ kakul.cc -o kakul Потом запускаете программу командой Код ./kakul -------------------- |
|
|
![]()
Сообщение
#90
|
|
![]() Зануда Сообщений: 2 237 Спасибо сказали: 2894 раза ![]() |
Что за хрень с форматированием? Где табуляция, и зачем эти пустые строки после каждой операции?
И зачем писать код через консоль, и уж тем более в nano? Ты хочешь отбить желание программировать у однаклассников, чтобы конкурентов не было?) И да, что такое "op" и почему "какил"? |
|
|
![]()
Сообщение
#91
|
|
![]() laughed as one fey Сообщений: 12 167 Спасибо сказали: 20596 раз ![]() |
Гнусный извращенец.
Одноклассникам - только IDE (и под винду, ага), что-нибудь нетяжелое типа CodeBlocks. И да, в конце мейна - getchar() или что там сейчас ставят, мне когда-то непонимание, как сделать задержку после вывода серьезно отравило интерес к десктопам (и я продолжил клепать гуевые говноутилитки для мобил, доо) |
|
|
![]()
Сообщение
#92
|
|
![]() 😸🧡✊✌️ Сообщений: 16 397 Спасибо сказали: 3234 раза ![]() |
почему "какил"? Не какил, а Какул. Это город такой в Пакистане.что такое "op"? Сокращение от 'operation' или 'operator'.
-------------------- Я слежу за тобой!
![]() ![]() Цитата Всегда приятно осознавать, что кто-то делает что-то хуже, чем делал бы ты, если бы умел. Борис "Бонус" Репетур, "От винта!", выпуск 38. |
|
|
![]()
Сообщение
#93
|
|
![]() Зануда Сообщений: 2 237 Спасибо сказали: 2894 раза ![]() |
Цитата Сокращение от 'operation' или 'operator'. Не умничай) Я-то понял, а вот одноклассники не поймут. Я к тому, что в приличном обществе названия переменных полностью записывают (исключение - редкие устоявшиеся кейсы вроде let i = 0; i < 10; i++). |
|
|
![]()
Сообщение
#94
|
|
![]() 😸🧡✊✌️ Сообщений: 16 397 Спасибо сказали: 3234 раза ![]() |
Сейчас в БД одного нашего проекта слово method в именах полей сокращено до meth. Вот это непонятно и даже смешно. А op - устоявшееся сокращение.
-------------------- Я слежу за тобой!
![]() ![]() Цитата Всегда приятно осознавать, что кто-то делает что-то хуже, чем делал бы ты, если бы умел. Борис "Бонус" Репетур, "От винта!", выпуск 38. |
|
|
![]()
Сообщение
#95
|
|
![]() Разработчик Сообщений: 534 Спасибо сказали: 222 раза ![]() |
Гнусный извращенец. Одноклассникам - только IDE (и под винду, ага), что-нибудь нетяжелое типа CodeBlocks. И да, в конце мейна - getchar() или что там сейчас ставят, мне когда-то непонимание, как сделать задержку после вывода серьезно отравило интерес к десктопам (и я продолжил клепать гуевые говноутилитки для мобил, доо) Не знаю. СоdeBlocks слишком сложный. Я когда его поставил просто испугался. Куча непонятныйх надписей и настроек и вообще я не для чего он нужет этот CodeBlockes если он даже fheroes2 собрать не смог. Заругался что не умеет работать с make файлами. В терминале игра одной командой собирается а СоdeBlockes ее собрать не может. Кому он такой нужем ? ![]() -------------------- |
|
|
![]()
Сообщение
#96
|
|
![]() Разработчик Сообщений: 534 Спасибо сказали: 222 раза ![]() |
Программирование на C++ (Урок 3)
Дейлаем Русский Тетрис-Черепочки на свободных исходниках. Для этого понадобится. 1) Компилятор g++ 4.7 2) Cmake 2.8.12 3) Любой текcтовый редактор Во первых, качаем исходники обычной игры Тетрис (анлийская версия) https://github.com/Teyu/Tetris-SDL-game 2) Разархивируем куда нибудь 3) Создаем папку tetris Код mkdir tetris Переходим в папку tetris Код cd tetris И cmake собираем make файл скачаных исходников Код cmake ~/Tetris-SDL-game-master затем даем команду Код make собираем игру И запускаем ее командой Код ./Tetris Игра всем хороша с небольшим исключением. Во-первых все по английски. А во-вторых какая-то скучаная. Давайте сделаем ее по русский и слегка повеселей. Делаем по русски. Для этого открываем в редакторе файл Framework.cpp (вот этот https://github.com/Teyu/Tetris-SDL-game/blo...c/Framework.cpp ) Ищем в нем строки Код m_ptext_points = TTF_RenderText_Solid(font, "Points: ", text_color); m_ptext_level = TTF_RenderText_Solid(font, "Level: ", text_color); m_ptext_lines = TTF_RenderText_Solid(font, "Lines: ", text_color); И изменям их на Код m_ptext_points = TTF_RenderUTF8_Solid(font, "Очки: ", text_color); m_ptext_level = TTF_RenderUTF8_Solid(font, "Уровень: ", text_color); m_ptext_lines = TTF_RenderUTF8_Solid(font, "Слои черепов: ", text_color); Так же меням размер шрифтов строку Код font = TTF_OpenFont("FreeSans.ttf", 24); меняем на Код font = TTF_OpenFont("FreeSans.ttf", 20); Сохраняем файл (Ctrl-O) и собираем игру командой Код make Игра стала по русски, но все равно скучная, поэтому скачиваем архив с черепочками Вот он http://wiki.kvkozyrev.org/uroki/Skulls.zip И разархивируем его в папку ~/tetris/data И игра у нас стала русской и веселой! Домашнее задание к Уроку 3. Вставить в игру Тетрис-Черепочки задним фоном какую-нибудь веселую картинку ![]() ![]() ![]() -------------------- |
|
|
![]() ![]()
Сообщение
#97
|
|
![]() 😸🧡✊✌️ Сообщений: 16 397 Спасибо сказали: 3234 раза ![]() |
В терминале игра одной командой собирается а СоdeBlockes ее собрать не может. Вот так и вырастают в красноглазиков.
-------------------- Я слежу за тобой!
![]() ![]() Цитата Всегда приятно осознавать, что кто-то делает что-то хуже, чем делал бы ты, если бы умел. Борис "Бонус" Репетур, "От винта!", выпуск 38. |
|
|
![]()
Сообщение
#98
|
|
![]() laughed as one fey Сообщений: 12 167 Спасибо сказали: 20596 раз ![]() |
На самом деле таки да, вопрос в цели.
Если "смотрите, чему я научился" - то ради бога, хозяин-барин. Если "я хочу вас научить" - то лучше все же не бить людей лбом о порог вхождения. |
|
|
![]()
Сообщение
#99
|
|
![]() Разработчик Сообщений: 534 Спасибо сказали: 222 раза ![]() |
На самом деле таки да, вопрос в цели. Если "смотрите, чему я научился" - то ради бога, хозяин-барин. Если "я хочу вас научить" - то лучше все же не бить людей лбом о порог вхождения. Почему бить лбом? Редатор текстов знают все. Выучить команду g++ и команду make и сделать по инструкции много проще чем разобраться с настройкой непонятной IDE, потому что никто не ошибется. IDE много сложней и непонятней чем команды. У меня что-то смогла собрать только одна IDE - Anjuta но она собирает только под Linux. СоdeBlokes вообще не умеет работать с make файлами и работает только со своим каким то cbp под Windows пришлось тоже собирать из консоли MinWG, а редактировать в WordPad. Еще я пробовал поставить Android Developer Studio но она у мне просто зависла протому что ей не хватило памяти. Поэтому для Аdroind я игру собрал тоже из терминала и в три команды Код ./changeAppSettings.sh -a android update project -p project -t android-23 ./build.sh И без всяких студий че три часа ставяться а потом виснут ![]() -------------------- |
|
|
![]()
Сообщение
#100
|
|
![]() Разработчик Сообщений: 534 Спасибо сказали: 222 раза ![]() |
Программирование на C++ (Урок 5) Делаем ЧАТ.
Чтобы сделать ЧАТ нам понадобится код сервера Код #include <iostream> #include <cstdlib> #include <string> #include <SDL_net.h> using namespace std; const unsigned short PORT = 1234; // The port our server will listen for incoming connecions on const unsigned short BUFFER_SIZE = 512; // Size of our message buffer const unsigned short MAX_SOCKETS = 4; // Max number of sockets const unsigned short MAX_CLIENTS = MAX_SOCKETS - 1; // Max number of clients in our socket set (-1 because server's listening socket takes the 1st socket in the set) // Messages to send back to any connecting client to let them know if we can accept the connection or not const string SERVER_NOT_FULL = "OK"; const string SERVER_FULL = "FULL"; int main(int argc, char **argv) { IPaddress serverIP; // The IP of the server (this will end up being 0.0.0.0 - which means roughly "any IP address") TCPsocket serverSocket; // The server socket that clients will use to connect to us TCPsocket clientSocket[MAX_CLIENTS]; // An array of sockets for the clients, we don't include the server socket (it's specified separately in the line above) bool socketIsFree[MAX_CLIENTS]; // An array of flags to keep track of which client sockets are free (so we know whether we can use the socket for a new client connection or not) char buffer[BUFFER_SIZE]; // Array of characters used to store the messages we receive int receivedByteCount = 0; // A variable to keep track of how many bytes (i.e. characters) we need to read for any given incoming message i.e. the size of the incoming data int clientCount = 0; // Count of how many clients are currently connected to the server bool shutdownServer = false; // Flag to control when to shut down the server // Initialise SDL_net (Note: We don't initialise or use normal SDL at all - only the SDL_net library!) if (SDLNet_Init() == -1) { cout << "Failed to intialise SDL_net: " << SDLNet_GetError() << endl; exit(-1); // Quit! } // Create the socket set with enough space to store our desired number of connections (i.e. sockets) SDLNet_SocketSet socketSet = SDLNet_AllocSocketSet(MAX_SOCKETS); if (socketSet == NULL) { cout << "Failed to allocate the socket set: " << SDLNet_GetError() << "\n"; exit(-1); // Quit! } else { cout << "Allocated socket set with size: " << MAX_SOCKETS << ", of which " << MAX_CLIENTS << " are availble for use by clients." << endl; } // Initialize all the client sockets (i.e. blank them ready for use!) for (int loop = 0; loop < MAX_CLIENTS; loop++) { clientSocket[loop] = NULL; socketIsFree[loop] = true; // Set all our sockets to be free (i.e. available for use for new client connections) } // Try to resolve the provided server hostname. If successful, this places the connection details in the serverIP object and creates a listening port on the provided port number // Note: Passing the second parameter as "NULL" means "make a listening port". SDLNet_ResolveHost returns one of two values: -1 if resolving failed, and 0 if resolving was successful int hostResolved = SDLNet_ResolveHost(&serverIP, NULL, PORT); if (hostResolved == -1) { cout << "Failed to resolve the server host: " << SDLNet_GetError() << endl; } else // If we resolved the host successfully, output the details { // Get our IP address in proper dot-quad format by breaking up the 32-bit unsigned host address and splitting it into an array of four 8-bit unsigned numbers... Uint8 * dotQuad = (Uint8*)&serverIP.host; //... and then outputting them cast to integers. Then read the last 16 bits of the serverIP object to get the port number cout << "Successfully resolved server host to IP: " << (unsigned short)dotQuad[0] << "." << (unsigned short)dotQuad[1] << "." << (unsigned short)dotQuad[2] << "." << (unsigned short)dotQuad[3]; cout << " port " << SDLNet_Read16(&serverIP.port) << endl << endl; } // Try to open the server socket serverSocket = SDLNet_TCP_Open(&serverIP); if (!serverSocket) { cout << "Failed to open the server socket: " << SDLNet_GetError() << "\n"; exit(-1); } else { cout << "Sucessfully created server socket." << endl; } // Add our server socket to the socket set SDLNet_TCP_AddSocket(socketSet, serverSocket); cout << "Awaiting clients..." << endl; // Main loop... do { // Check for activity on the entire socket set. The second parameter is the number of milliseconds to wait for. // For the wait-time, 0 means do not wait (high CPU!), -1 means wait for up to 49 days (no, really), and any other number is a number of milliseconds, i.e. 5000 means wait for 5 seconds int numActiveSockets = SDLNet_CheckSockets(socketSet, 0); if (numActiveSockets != 0) { cout << "There are currently " << numActiveSockets << " socket(s) with data to be processed." << endl; } // Check if our server socket has received any data // Note: SocketReady can only be called on a socket which is part of a set and that has CheckSockets called on it (the set, that is) // SDLNet_SocketRead returns non-zero for activity, and zero is returned for no activity. Which is a bit bass-ackwards IMHO, but there you go. int serverSocketActivity = SDLNet_SocketReady(serverSocket); // If there is activity on our server socket (i.e. a client has trasmitted data to us) then... if (serverSocketActivity != 0) { // If we have room for more clients... if (clientCount < MAX_CLIENTS) { // Find the first free socket in our array of client sockets int freeSpot = -99; for (int loop = 0; loop < MAX_CLIENTS; loop++) { if (socketIsFree[loop] == true) { //cout << "Found a free spot at element: " << loop << endl; socketIsFree[loop] = false; // Set the socket to be taken freeSpot = loop; // Keep the location to add our connection at that index in the array of client sockets break; // Break out of the loop straight away } } // ...accept the client connection and then... clientSocket[freeSpot] = SDLNet_TCP_Accept(serverSocket); // ...add the new client socket to the socket set (i.e. the list of sockets we check for activity) SDLNet_TCP_AddSocket(socketSet, clientSocket[freeSpot]); // Increase our client count clientCount++; // Send a message to the client saying "OK" to indicate the incoming connection has been accepted strcpy( buffer, SERVER_NOT_FULL.c_str() ); int msgLength = strlen(buffer) + 1; SDLNet_TCP_Send(clientSocket[freeSpot], (void *)buffer, msgLength); cout << "Client connected. There are now " << clientCount << " client(s) connected." << endl << endl; } else // If we don't have room for new clients... { cout << "*** Maximum client count reached - rejecting client connection ***" << endl; // Accept the client connection to clear it from the incoming connections list TCPsocket tempSock = SDLNet_TCP_Accept(serverSocket); // Send a message to the client saying "FULL" to tell the client to go away strcpy( buffer, SERVER_FULL.c_str() ); int msgLength = strlen(buffer) + 1; SDLNet_TCP_Send(tempSock, (void *)buffer, msgLength); // Shutdown, disconnect, and close the socket to the client SDLNet_TCP_Close(tempSock); } } // End of if server socket is has activity check // Loop to check all possible client sockets for activity for (int clientNumber = 0; clientNumber < MAX_CLIENTS; clientNumber++) { // If the socket is ready (i.e. it has data we can read)... (SDLNet_SocketReady returns non-zero if there is activity on the socket, and zero if there is no activity) int clientSocketActivity = SDLNet_SocketReady(clientSocket[clientNumber]); //cout << "Just checked client number " << clientNumber << " and received activity status is: " << clientSocketActivity << endl; // If there is any activity on the client socket... if (clientSocketActivity != 0) { // Check if the client socket has transmitted any data by reading from the socket and placing it in the buffer character array receivedByteCount = SDLNet_TCP_Recv(clientSocket[clientNumber], buffer, BUFFER_SIZE); // If there's activity, but we didn't read anything from the client socket, then the client has disconnected... if (receivedByteCount <= 0) { //...so output a suitable message and then... cout << "Client " << clientNumber << " disconnected." << endl << endl; //... remove the socket from the socket set, then close and reset the socket ready for re-use and finally... SDLNet_TCP_DelSocket(socketSet, clientSocket[clientNumber]); SDLNet_TCP_Close(clientSocket[clientNumber]); clientSocket[clientNumber] = NULL; // ...free up their slot so it can be reused... socketIsFree[clientNumber] = true; // ...and decrement the count of connected clients. clientCount--; cout << "Server is now connected to: " << clientCount << " client(s)." << endl << endl; } else // If we read some data from the client socket... { // Output the message the server received to the screen cout << "Received: >>>> " << buffer << " from client number: " << clientNumber << endl; // Send message to all other connected clients int originatingClient = clientNumber; for (int loop = 0; loop < MAX_CLIENTS; loop++) { // Send a message to the client saying "OK" to indicate the incoming connection has been accepted //strcpy( buffer, SERVER_NOT_FULL.c_str() ); int msgLength = strlen(buffer) + 1; // If the message length is more than 1 (i.e. client pressed enter without entering any other text), then // send the message to all connected clients except the client who originated the message in the first place if (msgLength > 1 && loop != originatingClient && socketIsFree[loop] == false) { cout << "Retransmitting message: " << buffer << " (" << msgLength << " bytes) to client number: " << loop << endl; SDLNet_TCP_Send(clientSocket[loop], (void *)buffer, msgLength); } } // If the client told us to shut down the server, then set the flag to get us out of the main loop and shut down if ( strcmp(buffer, "shutdown") == 0 ) { shutdownServer = true; cout << "Disconnecting all clients and shutting down the server..." << endl << endl; } } } // End of if client socket is active check } // End of server socket check sockets loop } while (shutdownServer == false); // End of main loop // Free our socket set (i.e. all the clients in our socket set) SDLNet_FreeSocketSet(socketSet); // Close our server socket, cleanup SDL_net and finish! SDLNet_TCP_Close(serverSocket); SDLNet_Quit(); return 0; } Cобирать надо такой командой : Код g++ server.cc -w -lSDL_net -o server И код клинета Код // Includes for non-blocking keyboard input #include <stdlib.h> #include <string.h> #include <stdio.h> #include <termios.h> // If we do not include termios.h the client WILL compile but it WILL NOT WORK! #include <unistd.h> #include <fcntl.h> #include <iostream> #include <string> #include <SDL_net.h> using namespace std; const unsigned short PORT = 1234; // The port we are connecting to const unsigned short BUFFER_SIZE = 512; // Size of our message buffer (i.e. maximum length of characters in a message) struct termios orig_termios; // Function to reset the terminal to blocking mode void reset_terminal_mode() { tcsetattr(0, TCSANOW, &orig_termios); } // Sets the terminal mode to conio mode void set_conio_terminal_mode() { struct termios new_termios; // Take two copies - one for now, one for later tcgetattr(0, &orig_termios); memcpy(&new_termios, &orig_termios, sizeof(new_termios)); // register cleanup handler, and set the new terminal mode //atexit(reset_terminal_mode); // Commented out because I switch and swap terminal modes a lot - just remember to call reset_terminal_mode() when we finish up cfmakeraw(&new_termios); tcsetattr(0, TCSANOW, &new_termios); } // Fuction to check if a key has been pressed int kbHit() { // How long to wait for input // Note: As soon as we get input the wait is immediately over - so it's not like our typing rate is limited in any way! long waitSeconds = 1L; long waitMicroSeconds = 0L; struct timeval tv = { waitSeconds, waitMicroSeconds }; // Create a file descriptor set fd_set fds; FD_SET(0, &fds); return select(1, &fds, NULL, NULL, &tv); } // Function to read the contents of the keypress int getch() { int r; unsigned char c; if ((r = read(0, &c, sizeof(c))) < 0) { //cout << "About to return a number..." << endl; return r; } else { //cout << "About to return a character..." << endl; return c; } } int main(int argc, char **argv) { const char *host; // Where we store the host name IPaddress serverIP; // The IP we will connect to TCPsocket clientSocket; // The socket to use string serverName; // The server name string userInput = ""; // A string to hold our user input int inputLength = 0; // The length of our string in characters char buffer[BUFFER_SIZE]; // Array of character's we'll use to transmit our message. We get input into the userInput string for ease of use, then just copy it to this character array and send it. // Initialise SDL_net if (SDLNet_Init() < 0) { cout << "Failed to intialise SDN_net: " << SDLNet_GetError() << "\n"; exit(-1); // Quit! } // Ask the user for a server to connect to - can be entered as a hostname (i.e. localhost etc.) or an IP address (i.e. 127.0.0.1 etc.) cout << "Server Name: "; //getline(cin, serverName); // Uncomment this and remove the below line to change the server we're connecting to... serverName = "localhost"; // Create the socket set with enough space to store our desired number of connections (i.e. sockets) SDLNet_SocketSet socketSet = SDLNet_AllocSocketSet(1); if (socketSet == NULL) { cout << "Failed to allocate the socket set: " << SDLNet_GetError() << "\n"; exit(-1); // Quit! } else { cout << "Successfully allocated socket set." << endl; } // Try to resolve the host. If successful, this places the connection details in the serverIP object int hostResolved = SDLNet_ResolveHost(&serverIP, serverName.c_str(), PORT); if (hostResolved == -1) { cout << "Failed to resolve the server hostname: " << SDLNet_GetError() << "\nContinuing...\n"; } else // If we successfully resolved the host then output the details { // Get our IP address in proper dot-quad format by breaking up the 32-bit unsigned host address and splitting it into an array of four 8-bit unsigned numbers... Uint8 * dotQuad = (Uint8*)&serverIP.host; //... and then outputting them cast to integers. Then read the last 16 bits of the serverIP object to get the port number cout << "Successfully resolved host to IP: " << (unsigned short)dotQuad[0] << "." << (unsigned short)dotQuad[1] << "." << (unsigned short)dotQuad[2] << "." << (unsigned short)dotQuad[3]; cout << " port " << SDLNet_Read16(&serverIP.port) << endl << endl; } // Try to resolve the IP of the server, just for kicks if ((host = SDLNet_ResolveIP(&serverIP)) == NULL) { cout << "Failed to resolve the server IP address: " << SDLNet_GetError() << endl; } else { cout << "Successfully resolved IP to host: " << host << endl; } // Flag to keep track of when to disconnect and finish up. We initially set it so that we CANNOT connect, and only change this to false when we got an "OK" response from the server bool shutdownClient = true; // Try to open a connection to the server and quit out if we can't connect clientSocket = SDLNet_TCP_Open(&serverIP); if (!clientSocket) { cout << "Failed to open socket to server: " << SDLNet_GetError() << "\n"; exit(-1); } else // If we successfully opened a connection then check for the server response to our connection { cout << "Connection okay, about to read connection status from the server..." << endl; // Add our socket to the socket set for polling SDLNet_TCP_AddSocket(socketSet, clientSocket); // Wait for up to five seconds for a response from the server // Note: If we don't check the socket set and WAIT for the response, we'll be checking before the server can respond, and it'll look as if the server sent us nothing back int activeSockets = SDLNet_CheckSockets(socketSet, 5000); cout << "There are " << activeSockets << " socket(s) with data on them at the moment." << endl; // Check if we got a response from the server int gotServerResponse = SDLNet_SocketReady(clientSocket); if (gotServerResponse != 0) { cout << "Got a response from the server... " << endl; int serverResponseByteCount = SDLNet_TCP_Recv(clientSocket, buffer, BUFFER_SIZE); cout << "Got the following from server: " << buffer << "(" << serverResponseByteCount << " bytes)" << endl; // We got an okay from the server, so we can join! if ( strcmp(buffer, "OK") == 0 ) { // So set the flag to say we're not quitting out just yet shutdownClient = false; cout << "Joining server now..." << endl << endl; } else { cout << "Server is full... Terminating connection." << endl; } } else { cout << "No response from server..." << endl; } } // End of if we managed to open a connection to the server condition bool wrotePrompt = false; // Whether or not we've already written the prompt bool sendMessage = false; // Whether or not it's time to send the message (flips to true when the user presses return) // While it's not time to shutdown the client... while (shutdownClient == false) { // Write the prompt only once per line of input. This gets reset so that it's displayed again after a message is sent if (wrotePrompt == false) { cout << "Write something:" << endl; wrotePrompt = true; } // If we've detected that the user has pressed a key.. set_conio_terminal_mode(); int status = kbHit(); reset_terminal_mode(); //cout << "status is: " << status << endl; if (status != 0) { //cout << "key was pressed and status is" << status << endl; // Get the keypress set_conio_terminal_mode(); char theChar = getch(); reset_terminal_mode(); // Output the character to stdout cout << theChar; // Flush the character to the screen fflush(stdout); // If the keypressed wasn't return then add the character to our message string if ((int)theChar != 13) { //cout << "Got the character: " << theChar << " (which is number: " << int(theChar) << ")" << endl; // Add the character to our input string userInput += theChar; } else // Otherwise (if the user pressed enter) then send the message { //cout << "user pressed return" << endl; // Copy our user's string into our char array called "buffer" strcpy( buffer, userInput.c_str() ); // Calculate the length of our input and then add 1 (for the terminating character) to get the total number of characters we need to send inputLength = strlen(buffer) + 1; // Send the message to the server if (SDLNet_TCP_Send(clientSocket, (void *)buffer, inputLength) < inputLength) { cout << "Failed to send message: " << SDLNet_GetError() << endl; exit(-1); } else { //cout << "Message sent successfully." << endl; // If we've asked the server to shutdown or we want out then set the flag appropriately if (sendMessage == true && (userInput == "quit" || userInput == "exit" || userInput == "shutdown")) { shutdownClient = true; } // Reset for the next message cout << endl; wrotePrompt = false; sendMessage = false; userInput = ""; } } // End of message sending section } // End of if the user pressed a key test // Check our socket set for activity. Don't wait if there's nothing on the socket just continue int socketActive = SDLNet_CheckSockets(socketSet, 0); //cout << "Sockets with data on them at the moment: " << activeSockets << endl; if (socketActive != 0) { // Check if we got a response from the server int messageFromServer = SDLNet_SocketReady(clientSocket); if (messageFromServer != 0) { //cout << "Got a response from the server... " << endl; int serverResponseByteCount = SDLNet_TCP_Recv(clientSocket, buffer, BUFFER_SIZE); cout << "Received: " << buffer << endl;// "(" << serverResponseByteCount << " bytes)" << endl; if (strcmp(buffer, "shutdown") == 0) { cout << "Server is going down. Disconnecting..." << endl; shutdownClient = true; } } else { //cout << "No response from server..." << endl; } } // End of if socket has activity check } // End of main while loop // Close our socket, cleanup SDL_net, reset the terminal mode and finish! SDLNet_TCP_Close(clientSocket); SDLNet_Quit(); reset_terminal_mode(); return 0; } Код g++ client.cc -w -lSDL_net -o client И получаем вот такой ЧАТ -------------------- |
|
|
![]() ![]() |
Текстовая версия | Сейчас: 28 July 2025 - 05:51 |
Copyright by Алексей Крючков
![]() Programming by Degtyarev Dmitry |
|