first commit
This commit is contained in:
13
README.md
Normal file
13
README.md
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
## ncursestest
|
||||||
|
A basic ncurses proof of concept test
|
||||||
|
|
||||||
|
## network more complicated
|
||||||
|
A "complicated" network system that allows for ip address and port selection but dosn't use ncurses or have threading
|
||||||
|
|
||||||
|
## network test
|
||||||
|
A better network test that doesn't allow you to use anything besides address 127.0.0.1 and port 8080 but it features properly implemented threading. The lack of ncurses prevents it from being passable as a client/server chat program because the ui gets out of sync but otherwise it actually works
|
||||||
|
|
||||||
|
## thread test
|
||||||
|
A basic example of how to use pthread
|
||||||
|
|
||||||
|
further instructions for how to use these programs are in the comments in their respective source code files
|
||||||
18
ncurses test/Makefile
Normal file
18
ncurses test/Makefile
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
# Compiler and flags
|
||||||
|
CXX = g++
|
||||||
|
CXXFLAGS = -Wall -Wextra -O2 -std=c++17
|
||||||
|
|
||||||
|
# Linker flags
|
||||||
|
LDFLAGS = -lcurses
|
||||||
|
|
||||||
|
# Default target
|
||||||
|
all: ncursestest
|
||||||
|
|
||||||
|
# Build rule
|
||||||
|
ncursestest: ncursestest.cpp
|
||||||
|
$(CXX) $(CXXFLAGS) ncursestest.cpp -o ncursestest $(LDFLAGS)
|
||||||
|
|
||||||
|
# Clean build artifacts
|
||||||
|
clean:
|
||||||
|
rm -f ncursestest
|
||||||
|
|
||||||
BIN
ncurses test/ncursestest
Executable file
BIN
ncurses test/ncursestest
Executable file
Binary file not shown.
37
ncurses test/ncursestest.cpp
Normal file
37
ncurses test/ncursestest.cpp
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
#include <curses.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <cstring>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
initscr();//creates stdscr. important step
|
||||||
|
use_default_colors();//this apparently tells it to use default terminal colors whenever there is no color attribute applied
|
||||||
|
|
||||||
|
printw("Hello World\n");
|
||||||
|
printw("Please enter a string: ");
|
||||||
|
refresh();
|
||||||
|
char *arr = new char[1024];
|
||||||
|
getstr(arr);
|
||||||
|
printw("Wow I didn't think you'd type in THAT. You entered: ");
|
||||||
|
printw(arr);
|
||||||
|
|
||||||
|
start_color();
|
||||||
|
init_pair(1,COLOR_RED, COLOR_BLUE);
|
||||||
|
attron(COLOR_PAIR(1));
|
||||||
|
printw("\nThe quick brown fox jumps over the lazy dog\n");
|
||||||
|
attroff(COLOR_PAIR(1));
|
||||||
|
|
||||||
|
mvprintw(17, 7, "BRUUUUUUUUH");
|
||||||
|
|
||||||
|
move(12,13);
|
||||||
|
attron(A_STANDOUT | A_UNDERLINE);
|
||||||
|
mvprintw(15, 3, "");
|
||||||
|
attroff(A_STANDOUT | A_UNDERLINE);
|
||||||
|
mvaddch(4,3, '@');
|
||||||
|
refresh();
|
||||||
|
getch();
|
||||||
|
endwin();
|
||||||
|
}
|
||||||
19
network more complicated/Makefile
Normal file
19
network more complicated/Makefile
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
# Compiler and flags
|
||||||
|
CXX = g++
|
||||||
|
CXXFLAGS = -Wall -Wextra -O2 -std=c++17
|
||||||
|
|
||||||
|
# Targets
|
||||||
|
all: client server
|
||||||
|
|
||||||
|
# Client build
|
||||||
|
client: client.cpp
|
||||||
|
$(CXX) $(CXXFLAGS) client.cpp -o client
|
||||||
|
|
||||||
|
# Server build
|
||||||
|
server: server.cpp
|
||||||
|
$(CXX) $(CXXFLAGS) server.cpp -o server
|
||||||
|
|
||||||
|
# Clean build artifacts
|
||||||
|
clean:
|
||||||
|
rm -f client server
|
||||||
|
|
||||||
BIN
network more complicated/client
Executable file
BIN
network more complicated/client
Executable file
Binary file not shown.
86
network more complicated/client.cpp
Normal file
86
network more complicated/client.cpp
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
/*this network test uses more complicated network functionality but doesnt use threads or ncurses.
|
||||||
|
that means you have to wait for the other end to send a message before getting to write a new message
|
||||||
|
to run, do ./client.cpp 127.0.0.1 8080
|
||||||
|
this one has args
|
||||||
|
*/
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <sys/uio.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <fstream>
|
||||||
|
using namespace std;
|
||||||
|
//Client side
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
//we need 2 things: ip address and port number, in that order
|
||||||
|
if(argc != 3)
|
||||||
|
{
|
||||||
|
cerr << "Usage: ip_address port" << endl; exit(0);
|
||||||
|
} //grab the IP address and port number
|
||||||
|
char *serverIp = argv[1]; int port = atoi(argv[2]);
|
||||||
|
//create a message buffer
|
||||||
|
char msg[1500];
|
||||||
|
//setup a socket and connection tools
|
||||||
|
struct hostent* host = gethostbyname(serverIp);
|
||||||
|
sockaddr_in sendSockAddr;
|
||||||
|
bzero((char*)&sendSockAddr, sizeof(sendSockAddr));
|
||||||
|
sendSockAddr.sin_family = AF_INET;
|
||||||
|
sendSockAddr.sin_addr.s_addr =
|
||||||
|
inet_addr(inet_ntoa(*(struct in_addr*)*host->h_addr_list));
|
||||||
|
sendSockAddr.sin_port = htons(port);
|
||||||
|
int clientSd = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
//try to connect...
|
||||||
|
int status = connect(clientSd,
|
||||||
|
(sockaddr*) &sendSockAddr, sizeof(sendSockAddr));
|
||||||
|
if(status < 0)
|
||||||
|
{
|
||||||
|
cout<<"Error connecting to socket!"<<endl;// break;
|
||||||
|
}
|
||||||
|
cout << "Connected to the server!" << endl;
|
||||||
|
int bytesRead, bytesWritten = 0;
|
||||||
|
struct timeval start1, end1;
|
||||||
|
gettimeofday(&start1, NULL);
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
cout << ">";
|
||||||
|
string data;
|
||||||
|
getline(cin, data);
|
||||||
|
memset(&msg, 0, sizeof(msg));//clear the buffer
|
||||||
|
strcpy(msg, data.c_str());
|
||||||
|
if(data == "exit")
|
||||||
|
{
|
||||||
|
send(clientSd, (char*)&msg, strlen(msg), 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
bytesWritten += send(clientSd, (char*)&msg, strlen(msg), 0);
|
||||||
|
cout << "Awaiting server response..." << endl;
|
||||||
|
memset(&msg, 0, sizeof(msg));//clear the buffer
|
||||||
|
bytesRead += recv(clientSd, (char*)&msg, sizeof(msg), 0);
|
||||||
|
if(!strcmp(msg, "exit"))
|
||||||
|
{
|
||||||
|
cout << "Server has quit the session" << endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
cout << "Server: " << msg << endl;
|
||||||
|
}
|
||||||
|
gettimeofday(&end1, NULL);
|
||||||
|
close(clientSd);
|
||||||
|
cout << "********Session********" << endl;
|
||||||
|
cout << "Bytes written: " << bytesWritten <<
|
||||||
|
" Bytes read: " << bytesRead << endl;
|
||||||
|
cout << "Elapsed time: " << (end1.tv_sec- start1.tv_sec)
|
||||||
|
<< " secs" << endl;
|
||||||
|
cout << "Connection closed" << endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
BIN
network more complicated/server
Executable file
BIN
network more complicated/server
Executable file
Binary file not shown.
117
network more complicated/server.cpp
Normal file
117
network more complicated/server.cpp
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
/*this network test uses more complicated network functionality but doesnt use threads or ncurses.
|
||||||
|
that means you have to wait for the other end to send a message before getting to write a new message
|
||||||
|
to run, do ./server.cpp 8080
|
||||||
|
this one has args
|
||||||
|
*/
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <sys/uio.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <fstream>
|
||||||
|
using namespace std;
|
||||||
|
//Server side
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
//for the server, we only need to specify a port number
|
||||||
|
if(argc != 2)
|
||||||
|
{
|
||||||
|
cerr << "Usage: port" << endl;
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
//grab the port number
|
||||||
|
int port = atoi(argv[1]);
|
||||||
|
//buffer to send and receive messages with
|
||||||
|
char msg[1500];
|
||||||
|
|
||||||
|
//setup a socket and connection tools
|
||||||
|
sockaddr_in servAddr;
|
||||||
|
bzero((char*)&servAddr, sizeof(servAddr));
|
||||||
|
servAddr.sin_family = AF_INET;
|
||||||
|
servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||||
|
servAddr.sin_port = htons(port);
|
||||||
|
|
||||||
|
//open stream oriented socket with internet address
|
||||||
|
//also keep track of the socket descriptor
|
||||||
|
int serverSd = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
if(serverSd < 0)
|
||||||
|
{
|
||||||
|
cerr << "Error establishing the server socket" << endl;
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
//bind the socket to its local address
|
||||||
|
int bindStatus = bind(serverSd, (struct sockaddr*) &servAddr,
|
||||||
|
sizeof(servAddr));
|
||||||
|
if(bindStatus < 0)
|
||||||
|
{
|
||||||
|
cerr << "Error binding socket to local address" << endl;
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
cout << "Waiting for a client to connect..." << endl;
|
||||||
|
//listen for up to 5 requests at a time
|
||||||
|
listen(serverSd, 5);
|
||||||
|
//receive a request from client using accept
|
||||||
|
//we need a new address to connect with the client
|
||||||
|
sockaddr_in newSockAddr;
|
||||||
|
socklen_t newSockAddrSize = sizeof(newSockAddr);
|
||||||
|
//accept, create a new socket descriptor to
|
||||||
|
//handle the new connection with client
|
||||||
|
int newSd = accept(serverSd, (sockaddr *)&newSockAddr, &newSockAddrSize);
|
||||||
|
if(newSd < 0)
|
||||||
|
{
|
||||||
|
cerr << "Error accepting request from client!" << endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
cout << "Connected with client!" << endl;
|
||||||
|
//lets keep track of the session time
|
||||||
|
struct timeval start1, end1;
|
||||||
|
gettimeofday(&start1, NULL);
|
||||||
|
//also keep track of the amount of data sent as well
|
||||||
|
int bytesRead, bytesWritten = 0;
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
//receive a message from the client (listen)
|
||||||
|
cout << "Awaiting client response..." << endl;
|
||||||
|
memset(&msg, 0, sizeof(msg));//clear the buffer
|
||||||
|
bytesRead += recv(newSd, (char*)&msg, sizeof(msg), 0);
|
||||||
|
if(!strcmp(msg, "exit"))
|
||||||
|
{
|
||||||
|
cout << "Client has quit the session" << endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
cout << "Client: " << msg << endl;
|
||||||
|
cout << ">";
|
||||||
|
string data;
|
||||||
|
getline(cin, data);
|
||||||
|
memset(&msg, 0, sizeof(msg)); //clear the buffer
|
||||||
|
strcpy(msg, data.c_str());
|
||||||
|
if(data == "exit")
|
||||||
|
{
|
||||||
|
//send to the client that server has closed the connection
|
||||||
|
send(newSd, (char*)&msg, strlen(msg), 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//send the message to client
|
||||||
|
bytesWritten += send(newSd, (char*)&msg, strlen(msg), 0);
|
||||||
|
}
|
||||||
|
//we need to close the socket descriptors after we're all done
|
||||||
|
gettimeofday(&end1, NULL);
|
||||||
|
close(newSd);
|
||||||
|
close(serverSd);
|
||||||
|
cout << "********Session********" << endl;
|
||||||
|
cout << "Bytes written: " << bytesWritten << " Bytes read: " << bytesRead << endl;
|
||||||
|
cout << "Elapsed time: " << (end1.tv_sec - start1.tv_sec)
|
||||||
|
<< " secs" << endl;
|
||||||
|
cout << "Connection closed..." << endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
19
network test/Makefile
Normal file
19
network test/Makefile
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
# Compiler and flags
|
||||||
|
CXX = g++
|
||||||
|
CXXFLAGS = -Wall -Wextra -O2 -std=c++17
|
||||||
|
|
||||||
|
# Targets
|
||||||
|
all: client server
|
||||||
|
|
||||||
|
# Client build
|
||||||
|
client: client.cpp
|
||||||
|
$(CXX) $(CXXFLAGS) client.cpp -o client
|
||||||
|
|
||||||
|
# Server build
|
||||||
|
server: server.cpp
|
||||||
|
$(CXX) $(CXXFLAGS) server.cpp -o server
|
||||||
|
|
||||||
|
# Clean build artifacts
|
||||||
|
clean:
|
||||||
|
rm -f client server
|
||||||
|
|
||||||
BIN
network test/client
Executable file
BIN
network test/client
Executable file
Binary file not shown.
94
network test/client.cpp
Normal file
94
network test/client.cpp
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
|
||||||
|
// Client side C/C++ program to demonstrate Socket programming
|
||||||
|
//this uses threads to allow a server and a client to do network chat stuff over 127.0.0.1:8080. the ui is out of sync because it doesn't use ncurses but the message sending and printing part still works
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <string>
|
||||||
|
#include <iostream>
|
||||||
|
#include <thread>
|
||||||
|
#define PORT 8080
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
/#include <windows.h>;
|
||||||
|
void fnsleep(unsigned milliseconds)
|
||||||
|
{
|
||||||
|
Sleep(milliseconds);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
#include <unistd.h>
|
||||||
|
void fnsleep(unsigned milliseconds)
|
||||||
|
{
|
||||||
|
usleep(milliseconds * 1000);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void checkForNewMsgs(int socket, int valreaded, int otherNum);
|
||||||
|
|
||||||
|
void checkForNewMsgs(int socket, int valreaded, int otherNum)
|
||||||
|
{
|
||||||
|
int valreadOne;
|
||||||
|
char newBuffer[1024] = {0};
|
||||||
|
while (3 == 3 && newBuffer != "exit")
|
||||||
|
{
|
||||||
|
for(int i = 0; i < 1024; i++)
|
||||||
|
{
|
||||||
|
newBuffer[i] = char(0);
|
||||||
|
}
|
||||||
|
valreadOne = read( socket , newBuffer, 1024);
|
||||||
|
if (newBuffer != "")
|
||||||
|
{
|
||||||
|
cout << "Server: ";
|
||||||
|
printf("%s\n",newBuffer );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fnsleep(1000);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char const *argv[])
|
||||||
|
{
|
||||||
|
int sock = 0, valread;
|
||||||
|
struct sockaddr_in serv_addr;
|
||||||
|
char *hello = "Hello from client";
|
||||||
|
char buffer[1024] = {0};
|
||||||
|
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
|
||||||
|
{
|
||||||
|
printf("\n Socket creation error \n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
serv_addr.sin_family = AF_INET;
|
||||||
|
serv_addr.sin_port = htons(PORT);
|
||||||
|
|
||||||
|
// Convert IPv4 and IPv6 addresses from text to binary form
|
||||||
|
if(inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr)<=0)
|
||||||
|
{
|
||||||
|
printf("\nInvalid address/ Address not supported \n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
|
||||||
|
{
|
||||||
|
printf("\nConnection Failed \n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
string message;
|
||||||
|
thread t(checkForNewMsgs, sock, valread, 1024);
|
||||||
|
t.detach();
|
||||||
|
while (message != "exit")
|
||||||
|
{
|
||||||
|
cout << "> ";
|
||||||
|
getline(cin, message);
|
||||||
|
send(sock , message.c_str() , strlen(message.c_str()) , 0 );
|
||||||
|
|
||||||
|
//printf("Hello message sent\n");
|
||||||
|
//valread = read( sock , buffer, 1024);
|
||||||
|
//printf("%s\n",buffer );
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
BIN
network test/server
Executable file
BIN
network test/server
Executable file
Binary file not shown.
114
network test/server.cpp
Normal file
114
network test/server.cpp
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
|
||||||
|
// Server side C/C++ program to demonstrate Socket programming
|
||||||
|
//this uses threads to allow a server and a client to do network chat stuff over 127.0.0.1:8080. the ui is out of sync because it doesn't use ncurses but the message sending and printing part still works
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <thread>
|
||||||
|
#include <iostream>
|
||||||
|
using namespace std;
|
||||||
|
#define PORT 8080
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
/#include <windows.h>;
|
||||||
|
void fnsleep(unsigned milliseconds)
|
||||||
|
{
|
||||||
|
Sleep(milliseconds);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
#include <unistd.h>
|
||||||
|
void fnsleep(unsigned milliseconds)
|
||||||
|
{
|
||||||
|
usleep(milliseconds * 1000);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void checkForNewMsgs(int socket, int valreaded, int otherNum);
|
||||||
|
|
||||||
|
void checkForNewMsgs(int socket, int valreaded, int otherNum)
|
||||||
|
{
|
||||||
|
int valreadOne;
|
||||||
|
char newBuffer[1024] = {0};
|
||||||
|
while (3 == 3 && newBuffer != "exit")
|
||||||
|
{
|
||||||
|
//printf("Client: ");
|
||||||
|
for(int i = 0; i < 1024; i++)
|
||||||
|
{
|
||||||
|
newBuffer[i] = char(0);
|
||||||
|
}
|
||||||
|
valreadOne = read( socket , newBuffer, 1024);
|
||||||
|
if (newBuffer != "")
|
||||||
|
{
|
||||||
|
printf("Client: ");
|
||||||
|
printf("%s\n",newBuffer );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fnsleep(1000);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char const *argv[])
|
||||||
|
{
|
||||||
|
int server_fd, new_socket, valread;
|
||||||
|
struct sockaddr_in address;
|
||||||
|
int opt = 1;
|
||||||
|
int addrlen = sizeof(address);
|
||||||
|
char buffer[1024] = {0};
|
||||||
|
char *hello = "Hello from server";
|
||||||
|
|
||||||
|
// Creating socket file descriptor
|
||||||
|
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0)
|
||||||
|
{
|
||||||
|
perror("socket failed");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Forcefully attaching socket to the port 8080
|
||||||
|
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT,
|
||||||
|
&opt, sizeof(opt)))
|
||||||
|
{
|
||||||
|
perror("setsockopt");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
address.sin_family = AF_INET;
|
||||||
|
address.sin_addr.s_addr = INADDR_ANY;
|
||||||
|
address.sin_port = htons( PORT );
|
||||||
|
|
||||||
|
// Forcefully attaching socket to the port 8080
|
||||||
|
if (bind(server_fd, (struct sockaddr *)&address,
|
||||||
|
sizeof(address))<0)
|
||||||
|
{
|
||||||
|
perror("bind failed");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
if (listen(server_fd, 3) < 0)
|
||||||
|
{
|
||||||
|
perror("listen");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
if ((new_socket = accept(server_fd, (struct sockaddr *)&address,
|
||||||
|
(socklen_t*)&addrlen))<0)
|
||||||
|
{
|
||||||
|
perror("accept");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
string message;
|
||||||
|
thread t(checkForNewMsgs, new_socket, valread, 1024);
|
||||||
|
t.detach();
|
||||||
|
while (message != "exit")
|
||||||
|
{
|
||||||
|
//string message;
|
||||||
|
cout << "> ";
|
||||||
|
getline(cin, message);
|
||||||
|
//valread = read( new_socket , buffer, 1024);
|
||||||
|
//printf("%s\n",buffer );
|
||||||
|
send(new_socket , message.c_str() , strlen(message.c_str()) , 0 );
|
||||||
|
//cout << "Hello message sent" << endl;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
21
thread test/Makefile
Normal file
21
thread test/Makefile
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# Compiler and flags
|
||||||
|
CXX = g++
|
||||||
|
CXXFLAGS = -pthread -Wall -Wextra -O2 -std=c++17
|
||||||
|
|
||||||
|
# Linker flags
|
||||||
|
LDFLAGS = -lcurses
|
||||||
|
|
||||||
|
# Default target
|
||||||
|
all: thread threadncurses
|
||||||
|
|
||||||
|
# Build rule
|
||||||
|
thread: thread.cpp
|
||||||
|
$(CXX) $(CXXFLAGS) thread.cpp -o thread $(LDFLAGS)
|
||||||
|
|
||||||
|
threadncurses: threadncurses.cpp
|
||||||
|
$(CXX) $(CXXFLAGS) threadncurses.cpp -o threadncurses $(LDFLAGS)
|
||||||
|
|
||||||
|
# Clean build artifacts
|
||||||
|
clean:
|
||||||
|
rm -f thread threadncurses
|
||||||
|
|
||||||
BIN
thread test/thread
Executable file
BIN
thread test/thread
Executable file
Binary file not shown.
49
thread test/thread.cpp
Normal file
49
thread test/thread.cpp
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
//compile with "g++ -pthread thread.cpp -o main"
|
||||||
|
//note to self: try to use ncurses in the next one
|
||||||
|
#include <iostream>
|
||||||
|
#include <thread>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
//this part has never been tested and is unlikely to work
|
||||||
|
#include <windows.h>;
|
||||||
|
void fnsleep(unsigned milliseconds)
|
||||||
|
{
|
||||||
|
Sleep(milliseconds);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
#include <unistd.h>
|
||||||
|
void fnsleep(unsigned milliseconds)
|
||||||
|
{
|
||||||
|
usleep(milliseconds * 1000);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void helloWorld(int y)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 10; i++)
|
||||||
|
{
|
||||||
|
//a terrible, awful way of getting linux terminal text colors without ncurses.
|
||||||
|
cout << "\033[1;31mbold red text\033[0m\n";
|
||||||
|
cout << "\x1B[32mAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x1B[0m\n";
|
||||||
|
cout << "Hello world #" << i + 1 << endl;
|
||||||
|
fnsleep(1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
thread thread_object(helloWorld, 1);
|
||||||
|
cout << "This string gets printed after running the hello world function but prints BEFORE helloworld prints. That means this program uses threads" << endl;
|
||||||
|
//use detach to make the thread run asychronoussly. use join to WAIT HERE until its finished. Try it out! (i tested both cases and it works on my machine)
|
||||||
|
//thread_object.detach();
|
||||||
|
thread_object.join();
|
||||||
|
cout << "Please enter your name: " << endl;
|
||||||
|
string name;
|
||||||
|
cin >> name;
|
||||||
|
cout << name << " is a [redacted for academic purposes]" << endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
BIN
thread test/threadncurses
Executable file
BIN
thread test/threadncurses
Executable file
Binary file not shown.
90
thread test/threadncurses.cpp
Normal file
90
thread test/threadncurses.cpp
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
//compile with "g++ -pthread threadncurses.cpp -o main -lncurses"
|
||||||
|
//the same as thread.cpp but it uses ncurses instead. This proves that ncurses can work even if its in a seperate thread
|
||||||
|
//this is a very functional example of ncurses and asynchronous threading working in the same program
|
||||||
|
#include <iostream>
|
||||||
|
#include <thread>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <ncurses.h>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
//this part has never been tested and is unlikely to work
|
||||||
|
#include <windows.h>;
|
||||||
|
void fnsleep(unsigned milliseconds)
|
||||||
|
{
|
||||||
|
Sleep(milliseconds);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
#include <unistd.h>
|
||||||
|
void fnsleep(unsigned milliseconds)
|
||||||
|
{
|
||||||
|
usleep(milliseconds * 1000);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void helloWorld(int y)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 10; i++)
|
||||||
|
{
|
||||||
|
//store the cursor positions here
|
||||||
|
int y, x;
|
||||||
|
int yy, xx;
|
||||||
|
int xBefore;
|
||||||
|
int yBefore;
|
||||||
|
start_color();
|
||||||
|
init_pair(1, COLOR_RED, COLOR_BLUE);
|
||||||
|
if (i != 0)
|
||||||
|
{
|
||||||
|
//print the hello world lines
|
||||||
|
getyx(stdscr, yBefore, xBefore);
|
||||||
|
move(2, 0);
|
||||||
|
clrtoeol();
|
||||||
|
mvprintw(2, 0, "Hello world #");
|
||||||
|
int icantthinkofanameforthis = i + 1;
|
||||||
|
printw(to_string(icantthinkofanameforthis).c_str());//an annoying but reliable way to get this to work
|
||||||
|
printw("\n");
|
||||||
|
move(yBefore, xBefore); //move the cursor back to where is was before to allow for a fluid typing experience (i.e. its possible to mess this part up if you do it wrong)
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
attron(COLOR_PAIR(1));
|
||||||
|
attron(A_BOLD);
|
||||||
|
getyx(stdscr, yy, xx);
|
||||||
|
printw("bold red text\n");
|
||||||
|
attroff(COLOR_PAIR(1));
|
||||||
|
printw("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n");
|
||||||
|
attroff(A_BOLD);
|
||||||
|
printw("Hello world #");
|
||||||
|
int icantthinkofanameforthis = i + 1;
|
||||||
|
printw(to_string(icantthinkofanameforthis).c_str());//an annoying but reliable way to get this to work
|
||||||
|
printw("\n");
|
||||||
|
move(3, 25); //the default text-entry position
|
||||||
|
}
|
||||||
|
|
||||||
|
refresh();
|
||||||
|
fnsleep(1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
initscr();
|
||||||
|
use_default_colors();
|
||||||
|
move(3, 0);
|
||||||
|
printw("Please enter your name: \n");
|
||||||
|
move(0, 0);
|
||||||
|
|
||||||
|
thread thread_object(helloWorld, 1);
|
||||||
|
thread_object.detach();
|
||||||
|
|
||||||
|
char *name = new char[99];
|
||||||
|
getstr(name);
|
||||||
|
printw(name);
|
||||||
|
printw(" is a [redacted for academic purposes]\n");
|
||||||
|
printw("Press any key to continue");
|
||||||
|
getch();
|
||||||
|
endwin();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user