├── .gitignore ├── README.md ├── LICENSE ├── tcp-Client.cpp └── tcp-Server.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Simple-TCP-Server-Client-CPP-Example 2 | C++ socket example 3 | 4 | Source code belongs to: 5 | https://simpledevcode.wordpress.com/2016/06/16/client-server-chat-in-c-using-sockets/ 6 | 7 | To use on Linux: 8 | 9 | Open terminal and copy-paste following lines: 10 | 11 | ``` 12 | cd INTO_CPP_FOLDER 13 | g++ tcp-Server.cpp -o server 14 | ./server 8080 15 | ``` 16 | Open another terminal and copy-paste following lines: 17 | 18 | 19 | ``` 20 | cd INTO_CPP_FOLDER 21 | g++ tcp-Client.cpp -o client 22 | ./client 127.0.0.1 8080 23 | ``` 24 | Note: This is for only Local usage. 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 bozkurthan 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /tcp-Client.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | using namespace std; 18 | //Client side 19 | int main(int argc, char *argv[]) 20 | { 21 | //we need 2 things: ip address and port number, in that order 22 | if(argc != 3) 23 | { 24 | cerr << "Usage: ip_address port" << endl; exit(0); 25 | } //grab the IP address and port number 26 | char *serverIp = argv[1]; int port = atoi(argv[2]); 27 | //create a message buffer 28 | char msg[1500]; 29 | //setup a socket and connection tools 30 | struct hostent* host = gethostbyname(serverIp); 31 | sockaddr_in sendSockAddr; 32 | bzero((char*)&sendSockAddr, sizeof(sendSockAddr)); 33 | sendSockAddr.sin_family = AF_INET; 34 | sendSockAddr.sin_addr.s_addr = 35 | inet_addr(inet_ntoa(*(struct in_addr*)*host->h_addr_list)); 36 | sendSockAddr.sin_port = htons(port); 37 | int clientSd = socket(AF_INET, SOCK_STREAM, 0); 38 | //try to connect... 39 | int status = connect(clientSd, 40 | (sockaddr*) &sendSockAddr, sizeof(sendSockAddr)); 41 | if(status < 0) 42 | { 43 | cout<<"Error connecting to socket!"<"; 53 | string data; 54 | getline(cin, data); 55 | memset(&msg, 0, sizeof(msg));//clear the buffer 56 | strcpy(msg, data.c_str()); 57 | if(data == "exit") 58 | { 59 | send(clientSd, (char*)&msg, strlen(msg), 0); 60 | break; 61 | } 62 | bytesWritten += send(clientSd, (char*)&msg, strlen(msg), 0); 63 | cout << "Awaiting server response..." << endl; 64 | memset(&msg, 0, sizeof(msg));//clear the buffer 65 | bytesRead += recv(clientSd, (char*)&msg, sizeof(msg), 0); 66 | if(!strcmp(msg, "exit")) 67 | { 68 | cout << "Server has quit the session" << endl; 69 | break; 70 | } 71 | cout << "Server: " << msg << endl; 72 | } 73 | gettimeofday(&end1, NULL); 74 | close(clientSd); 75 | cout << "********Session********" << endl; 76 | cout << "Bytes written: " << bytesWritten << 77 | " Bytes read: " << bytesRead << endl; 78 | cout << "Elapsed time: " << (end1.tv_sec- start1.tv_sec) 79 | << " secs" << endl; 80 | cout << "Connection closed" << endl; 81 | return 0; 82 | } 83 | -------------------------------------------------------------------------------- /tcp-Server.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | using namespace std; 18 | //Server side 19 | int main(int argc, char *argv[]) 20 | { 21 | //for the server, we only need to specify a port number 22 | if(argc != 2) 23 | { 24 | cerr << "Usage: port" << endl; 25 | exit(0); 26 | } 27 | //grab the port number 28 | int port = atoi(argv[1]); 29 | //buffer to send and receive messages with 30 | char msg[1500]; 31 | 32 | //setup a socket and connection tools 33 | sockaddr_in servAddr; 34 | bzero((char*)&servAddr, sizeof(servAddr)); 35 | servAddr.sin_family = AF_INET; 36 | servAddr.sin_addr.s_addr = htonl(INADDR_ANY); 37 | servAddr.sin_port = htons(port); 38 | 39 | //open stream oriented socket with internet address 40 | //also keep track of the socket descriptor 41 | int serverSd = socket(AF_INET, SOCK_STREAM, 0); 42 | if(serverSd < 0) 43 | { 44 | cerr << "Error establishing the server socket" << endl; 45 | exit(0); 46 | } 47 | //bind the socket to its local address 48 | int bindStatus = bind(serverSd, (struct sockaddr*) &servAddr, 49 | sizeof(servAddr)); 50 | if(bindStatus < 0) 51 | { 52 | cerr << "Error binding socket to local address" << endl; 53 | exit(0); 54 | } 55 | cout << "Waiting for a client to connect..." << endl; 56 | //listen for up to 5 requests at a time 57 | listen(serverSd, 5); 58 | //receive a request from client using accept 59 | //we need a new address to connect with the client 60 | sockaddr_in newSockAddr; 61 | socklen_t newSockAddrSize = sizeof(newSockAddr); 62 | //accept, create a new socket descriptor to 63 | //handle the new connection with client 64 | int newSd = accept(serverSd, (sockaddr *)&newSockAddr, &newSockAddrSize); 65 | if(newSd < 0) 66 | { 67 | cerr << "Error accepting request from client!" << endl; 68 | exit(1); 69 | } 70 | cout << "Connected with client!" << endl; 71 | //lets keep track of the session time 72 | struct timeval start1, end1; 73 | gettimeofday(&start1, NULL); 74 | //also keep track of the amount of data sent as well 75 | int bytesRead, bytesWritten = 0; 76 | while(1) 77 | { 78 | //receive a message from the client (listen) 79 | cout << "Awaiting client response..." << endl; 80 | memset(&msg, 0, sizeof(msg));//clear the buffer 81 | bytesRead += recv(newSd, (char*)&msg, sizeof(msg), 0); 82 | if(!strcmp(msg, "exit")) 83 | { 84 | cout << "Client has quit the session" << endl; 85 | break; 86 | } 87 | cout << "Client: " << msg << endl; 88 | cout << ">"; 89 | string data; 90 | getline(cin, data); 91 | memset(&msg, 0, sizeof(msg)); //clear the buffer 92 | strcpy(msg, data.c_str()); 93 | if(data == "exit") 94 | { 95 | //send to the client that server has closed the connection 96 | send(newSd, (char*)&msg, strlen(msg), 0); 97 | break; 98 | } 99 | //send the message to client 100 | bytesWritten += send(newSd, (char*)&msg, strlen(msg), 0); 101 | } 102 | //we need to close the socket descriptors after we're all done 103 | gettimeofday(&end1, NULL); 104 | close(newSd); 105 | close(serverSd); 106 | cout << "********Session********" << endl; 107 | cout << "Bytes written: " << bytesWritten << " Bytes read: " << bytesRead << endl; 108 | cout << "Elapsed time: " << (end1.tv_sec - start1.tv_sec) 109 | << " secs" << endl; 110 | cout << "Connection closed..." << endl; 111 | return 0; 112 | } 113 | --------------------------------------------------------------------------------