c++: Simple TCP server not accepting data from client - c++

I have to create a simple tcp server that accepts some commands from the server and responds to them in a certain way. I started with just a simple thing in which server accepts anything from client as command and responds "In response to your command" to client 10 times as answer. But even this is not working. Please help.
server.cpp
# include <string.h>
# include <unistd.h>
# include <stdio.h>
# include <netdb.h>
# include <sys/types.h>
# include <sys/stat.h>
# include <sys/socket.h>
# include <netinet/in.h>
# include <iostream>
# include <fstream>
# include <string.h>
# include <stdlib.h>
# include <string>
# include <pthread.h>
# include <dirent.h>
using namespace std;
void *task1(void *);
static int connFd;
int main(int argc, char* argv[])
{
int pId, portNo, listenFd;
socklen_t len; //store size of the address
bool loop = false;
struct sockaddr_in svrAdd, clntAdd;
pthread_t threadA[3];
if (argc < 2)
{
cerr << "Syntax : ./server <port>" << endl;
return 0;
}
portNo = atoi(argv[1]);
if((portNo > 65535) || (portNo < 2000))
{
cerr << "Please enter a port number between 2000 - 65535" << endl;
return 0;
}
//create socket
listenFd = socket(AF_INET, SOCK_STREAM, 0);
if(listenFd < 0)
{
cerr << "Cannot open socket" << endl;
return 0;
}
bzero((char*) &svrAdd, sizeof(svrAdd));
svrAdd.sin_family = AF_INET;
svrAdd.sin_addr.s_addr = INADDR_ANY;
svrAdd.sin_port = htons(portNo);
//bind socket
if(bind(listenFd, (struct sockaddr *)&svrAdd, sizeof(svrAdd)) < 0)
{
cerr << "Cannot bind" << endl;
return 0;
}
listen(listenFd, 5);
len = sizeof(clntAdd);
int noThread = 0;
while (noThread < 3)
{
cout << "Listening" << endl;
//this is where client connects. svr will hang in this mode until client conn
connFd = accept(listenFd, (struct sockaddr *)&clntAdd, &len);
if (connFd < 0)
{
cerr << "Cannot accept connection" << endl;
return 0;
}
else
{
cout << "Connection successful" << endl;
}
pthread_create(&threadA[noThread], NULL, task1, NULL);
noThread++;
}
for(int i = 0; i < noThread; i++)
{
pthread_join(threadA[i], NULL);
}
cout << "All threads have joined" << endl;
}
void *task1 (void *dummyPt)
{
cout << "Thread No: " << pthread_self() << endl;
char test[300];
char outbuf[300];
bzero(outbuf, 301);
bzero(test, 301);
bool loop = false;
int recvdBytes = 0;
strcpy(outbuf, "Enter your username: \n");
write(connFd, outbuf, strlen(outbuf));
bzero(outbuf, 301);
read(connFd, test, 300);
string uname(test);
strcpy(outbuf, "You are logged in\n");
write(connFd, outbuf, strlen(outbuf));
bzero(outbuf, 301);
while(!loop)
{
bzero(test, 301);
read(connFd, test, 300);
string tester (test);
cout << tester << endl;
if(tester == "exit")
break;
for (int i=0; i<10; ++i)
{
strcpy(outbuf, "In response to your command");
write(connFd, outbuf, strlen(outbuf));
bzero(outbuf, 301);
}
}
cout << "\nClosing thread and conn" << endl;
close(connFd);
}
client.cpp
# include <string.h>
# include <cstring>
# include <unistd.h>
# include <stdio.h>
# include <netdb.h>
# include <sys/types.h>
# include <sys/socket.h>
# include <netinet/in.h>
# include <iostream>
# include <fstream>
# include <sstream>
# include <iomanip>
# include <strings.h>
# include <stdlib.h>
# include <string>
# include <time.h>
# include <vector>
using namespace std;
int main (int argc, char* argv[])
{
int sockFd, portNo;
bool loop = false;
struct sockaddr_in svrAdd;
struct hostent *server;
char inbuf[300];
int recvdBytes=0;
if(argc < 3)
{
cerr << "Syntax : ./client <host name> <port>"<<endl;
return 0;
}
portNo = atoi(argv[2]);
if((portNo > 65535) || (portNo < 2000))
{
cerr << "Please enter port number between 2000 - 65535"<<endl;
return 0;
}
//create client skt
sockFd = socket(AF_INET, SOCK_STREAM, 0);
if(sockFd < 0)
{
cerr << "Cannot open socket" << endl;
return 0;
}
server = gethostbyname(argv[1]);
if(server == NULL)
{
cerr << "Host does not exist" << endl;
return 0;
}
bzero((char *) &svrAdd, sizeof(svrAdd));
svrAdd.sin_family = AF_INET;
bcopy((char *) server -> h_addr, (char *) &svrAdd.sin_addr.s_addr, server -> h_length);
svrAdd.sin_port = htons(portNo);
int checker = connect(sockFd,(struct sockaddr *) &svrAdd, sizeof(svrAdd));
if (checker < 0)
{
cerr << "Cannot connect!" << endl;
return 0;
}
recvdBytes = read(sockFd, inbuf, 300);
cout << inbuf;
bzero(inbuf, 300);
cin >> inbuf;
write(sockFd, inbuf, strlen(inbuf)); // sending my user name to server
bzero(inbuf, 300);
read(sockFd, inbuf, 300); // recieving the message from server
cout << inbuf;
bzero(inbuf, 300);
// send commands to server
for(;;)
{
char s[300];
//cin.clear();
//cin.ignore(256, '\n');
cout << "Enter command: ";
bzero(s, 301);
cin.getline(s, 300);
write(sockFd, s, strlen(s));
// recieve data in response to your command
while(read(sockFd, inbuf, 300))
{
if(strcmp(inbuf, "done") == 0) // display the output
break;
cout << inbuf;
bzero(inbuf, 300);
}
}
}

Usual problems.
connFD should not be static. It should be a local variable in both main() and task1(), and it should be communicated to the started thread somehow. Otherwise the next client will clobber it and break the first client.
You aren't error-testing listen().
You're ignoring the result of read() everywhere. You have to store it into a variable and check it for -1, zero, or a positive value: only in the positive case should the loop continue; and the positive value should be used to limit the number of bytes in the buffer you regard as having been received.
You are ignoring the result of write() everywhere.
So at present there is no evidence that anything has been sent anywhere by anybody.

Related

Does get_nprocs_conf() always return 1 when using a virtual machine?

I'm supposed to use get_nprocs_conf() to get the number of execution contexts on my machine. I'm doing this because I am coding a server and client to interact with each other, and the server may only host get_nprocs_conf()-1 clients. Before I add code to my server to wait for an opening, I want to figure out this issue.
I'm running this code on a virtual machine because I'm using Linux and my desktop is Windows, and when I use said code above, my maximum number of clients is 0, meaning that get_nprocs_conf() only returns 1. Is this because I'm using a virtual machine and for some reason it only can use one execution context, or am I misunderstanding and my computer only has one execution context?
Provided below are my server and client programs.
Server Code:
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include <iostream>
#include <fstream>
#include <sys/sysinfo.h>
#include <vector>
#include <cstring>
#include <arpa/inet.h>
//#define BUFFER_SIZE 32
//May need to replace -1 with EXIT_FAILURE in all the exits
int main(int argc, char *argv[]) {
if(argc != 2) {
std::cout << "Need domain socket file name" << std::endl;
exit(-1);
}
struct sockaddr_un server;
char buffer[32];
unlink(argv[1]);
int serverSock = socket(AF_UNIX, SOCK_STREAM, 0);
if(serverSock < 0) {
perror("socket");
exit(EXIT_FAILURE);
}
std::clog << "SERVER STARTED" << std::endl;
size_t maxClients = get_nprocs_conf()-1;
std::clog << "\t" << "MAX CLIENTS: " << maxClients << std::endl;
memset(&server, 0, sizeof(server));
server.sun_family = AF_UNIX;
strncpy(server.sun_path, argv[1], sizeof(server.sun_path)-1);
int success = bind(serverSock, (const struct sockaddr *) &server,
sizeof(struct sockaddr_un));
if(success < 0) {
perror("bind");
exit(EXIT_FAILURE);
}
success = listen(serverSock, maxClients);
if(success < 0) {
perror("listen");
exit(EXIT_FAILURE);
}
while(true) {
std::cout << "Waiting for clients" << std::endl;
int clientSock = accept(serverSock, nullptr, nullptr);
if(clientSock < 0) {
perror("accept");
exit(EXIT_FAILURE);
}
std::clog << "CLIENT CONNECTED" << std::endl;
std::string path="";
std::string searchStr="";
char fileBuff[32];
char searchBuff[32];
memset(fileBuff, 0, 32);
success = read(clientSock, fileBuff, 32);
if(success < 0) {
perror("read");
exit(EXIT_FAILURE);
}
path = fileBuff;
std::cout << path << std::endl;
if(path.empty()) {
std::cout << "No path to file given" << std::endl;
exit(1);
}
memset(searchBuff, 0, 32);
success = read(clientSock, searchBuff, 32);
if(success < 0) {
perror("read");
exit(EXIT_FAILURE);
}
searchStr = searchBuff;
std::cout << searchStr << std::endl;
if(searchStr.empty()) {
std::cout << "No search string given" << std::endl;
exit(1);
}
std::ifstream inFile;
inFile.open(path);
std::string line = "";
int bytesSent = 0;
std::vector<std::string> allLines;
if(inFile.is_open()) {
while(std::getline(inFile, line)) {
if(line.find(searchStr, 0)!=std::string::npos) {
allLines.push_back(line);
//std::cout << line << std::endl;
}
}
}
//Sending over entire length of vector containing all lines to be sent.
long length = htonl(allLines.size());
success = write(clientSock, &length, sizeof(length));
if(success < 0) {
perror("write");
exit(EXIT_FAILURE);
}
for(int b=0; b<allLines.size(); b++) {
length = htonl(allLines[b].length());
success = write(clientSock, &length, sizeof(length));
if(success < 0) {
perror("write");
exit(EXIT_FAILURE);
}
success = write(clientSock, allLines[b].data(), allLines[b].length());
if(success < 0) {
perror("write");
exit(EXIT_FAILURE);
}
bytesSent += allLines[b].length();
}
//char end[] = {'\n'};
//write(clientSock, end, sizeof(char));
std::cout << "BYTES SENT: " << bytesSent << std::endl;
inFile.close();
close(clientSock);
}
//return 0;
}
Client Code:
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <sys/socket.h>
#include <unistd.h>
#include <iostream>
#include <fstream> //Don't think I'll need this
#include <errno.h>
#include <sys/un.h>
#include <sstream>
#include <arpa/inet.h>
#include <vector>
int main(int argc, char *argv[]){
if(argc != 4) {
std::cout << "Need domain socket file name, file path and name, " <<
"and search string" << std::endl;
exit(-1);
}
struct sockaddr_un client;
char buffer[64]; //Prof had 64 for client may need to change to 32 to match
int clientSock = socket(AF_UNIX, SOCK_STREAM, 0);
if(clientSock < 0) {
perror("socket");
exit(EXIT_FAILURE);
}
std::cout << "socket connected" << std::endl;
memset(&client, 0, sizeof(struct sockaddr_un));
client.sun_family = AF_UNIX;
strncpy(client.sun_path, argv[1], sizeof(client.sun_path)-1);
int connectClient = connect(clientSock, (const struct sockaddr *)&client,
sizeof(struct sockaddr_un));
if(connectClient < 0) {
fprintf(stderr, "The server is not working.\n");
exit(EXIT_FAILURE);
}
std::cout << "client connected" << std::endl;
//char arg2[] = {*argv[2],'\n'};
std::string path = argv[2];
std::cout << "Path: " << path << std::endl;
connectClient = write(clientSock, argv[2], path.length());
if(connectClient < 0) {
perror("write");
exit(EXIT_FAILURE);
}
std::string search = argv[3];
std::cout << "Search String: " << search << std::endl;
connectClient = write(clientSock, argv[3], search.length());
if(connectClient < 0) {
perror("write");
exit(EXIT_FAILURE);
}
//int servRet;
int lineCount=0;
int bytes_received=0;
//std::string line = "";
char length[sizeof(int)];
//std::string leng = "";
int num=0;
std::stringstream ss;
std::vector<std::string> allLines;
long size = 0;
read(clientSock, &size, sizeof(size));
size = ntohl(size);
for(int a=0; a<size; ++a) {
long length = 0;
std::string line = "";
connectClient = read(clientSock, &length, sizeof(length));
length = ntohl(length);
while(0 < length) {
char buffer[1024];
connectClient = read(clientSock, buffer, std::min<unsigned long>(sizeof(buffer),length));
line.append(buffer, connectClient);
length-=connectClient;
}
allLines.push_back(line);
lineCount++;
std::cout << lineCount << "\t" << line << std::endl;
bytes_received += line.length();
}
std::cout << "BYTES RECEIVED: " << bytes_received << std::endl;
close(clientSock);
return 0;
}
Right now everything in the server and client work as they should. I'm just hesitating to add code that waits for an execution context to open for another client to be read because it seems like it would never accept any clients since the sole execution context is being used by the server. Any clarification on my issue or on if I'm just using get_nprocs_conf() incorrectly would be greatly appreciated.

Sending and Receiving From a Server Simultaneously

The way my code is currently written only allows a message from the server to be read directly after input is taken and a message is sent. However, this code is for a chat server and must allow a read to occur at any time a message is sent.
#include <iostream>
#include <string>
#include <cstring>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#define SERVER_ADDRESS "127.0.0.1"
constexpr int server_port = 15555;
#define SERVER_SUCCESS "1"
#define SERVER_FAILURE "-1"
constexpr int msg_buffer_size = 4096;
int main(int argc, char *argv[])
{
struct sockaddr_in serv_addr;
int sock;
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
std::cerr << "Socket creation failed!" << std::endl;
return 1;
}
memset(&serv_addr, '0', sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(server_port);
if (inet_pton(AF_INET, SERVER_ADDRESS, &serv_addr.sin_addr) <= 0)
{
std::cerr << "Invalid server address!" << std::endl;
return 1;
}
if (connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0)
{
std::cerr << "Failed to connect to chat server!" << std::endl;
return 1;
}
int valread;
while (true)
{
std::cout << ">> ";
char msg[msg_buffer_size];
char return_msg[msg_buffer_size];
std::string input;
std::getline(std::cin, input);
if (input == "quit")
return 0;
if (input.length() > 4000)
{
std::cout << "Input length must be less than 4000 characters." << std::endl;
continue;
}
strcpy(msg, input.c_str());
if (send(sock, msg, strlen(msg), 0) < 0)
{
std::cout << "Error sending data." << std::endl;
continue;
}
if (recv(sock, return_msg, msg_buffer_size, 0) < 0)
{
std::cout << "Error receiving data." << std::endl;
continue;
}
std::string code(strtok(return_msg, " "));
if (code == SERVER_FAILURE)
std::cout << "Failure: " << strtok(NULL, "") << std::endl;
else
std::cout << strtok(NULL, "") << std::endl;
memset(msg, 0, msg_buffer_size);
memset(return_msg, 0, msg_buffer_size);
}
std::cout << "Exiting." << std::endl;
close(sock);
return 0;
}
What would be a correct way to allow the client to receive a message as soon as one is sent from the server? I was thinking about making a thread, but it seemed kind of redundant since I would be receiving in two places.

Server not receiving Client message

I am trying to create a server-client program where 2 clients can send messages to each other just like how one would chat in facebook. I was able to go up to the point where multiple clients can connect to the server but it seems like i fail to find a way for the server to receive any messages from a client.
Heres my code so far:
Server:
#include <iostream>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <list>
#define BUFFERSIZE 1024
#define PORTNUM 5001
#define MAXPARTICIPANTS 10
using namespace std;
int sockfd = 0;
int connfd = 0;
int clients[MAXPARTICIPANTS] = {};
bool dupe;
int receiver = 0;
struct sockaddr_in server_addr;
char sendBuff[BUFFERSIZE];
char receiveBuff[BUFFERSIZE];
void *getNewParticipant(void *arg){
while (1){
dupe = false;
connfd = accept(sockfd, (struct sockaddr*)NULL, NULL);
for(int i=0; i<MAXPARTICIPANTS; i++){
if(clients[i] == connfd){
dupe = true;
break;
}
}
if(!dupe){
for(int i=0; i<MAXPARTICIPANTS; i++){
if(clients[i] == 0){
clients[i] = connfd;
cout << connfd << " joined" << endl;
break;
}
}
for(int i=0; i<MAXPARTICIPANTS; i++){
cout << clients[i] << " ";
}
cout << endl;
sprintf(sendBuff, "%d joined the conversation", connfd);
for(int i=0; i<MAXPARTICIPANTS; i++){
if(clients[i] != 0){
write(clients[i], sendBuff, strlen(sendBuff));
}
}
}
sleep(1);
}
}
void *handleMessages(void *arg){
while(1){
if((receiver = read(sockfd, receiveBuff, sizeof(receiveBuff)-1)) > 0){
receiveBuff[receiver] = 0;
if(fputs(receiveBuff, stdout) == EOF){
cout << "ERROR" << endl;
}
cout << endl;
}
/*int receiver = recv(sockfd, receiveBuff, BUFFERSIZE, 0);
//if(receiver > 0){
cout << receiver << ": " << receiveBuff << endl;
for(int i=0; i<MAXPARTICIPANTS; i++){
if(clients[i] != 0){
write(clients[i], receiveBuff, strlen(receiveBuff));
}
}
//}*/
sleep(1);
}
}
int main(void){
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd < 0){
cout << "Failed to create Socket" << endl;
return -1;
}
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons(PORTNUM);
if(bind(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0){
cout << "Failed to bind socket" << endl;
return -1;
}
cout << "Setup complete. Waiting for clients...." << endl;
if(listen(sockfd, MAXPARTICIPANTS) < 0){
cout << "Failed to Listen" << endl;
return -1;
}
pthread_t tid[2];
pthread_create(&tid[0], NULL, getNewParticipant, NULL);
pthread_create(&tid[1], NULL, handleMessages, NULL);
while (1) {
}
}
Client
#include <iostream>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#define BUFFERSIZE 1024
#define PORTNUM 5001
using namespace std;
int main(){
int sockfd = 0, connfd = 0;
struct sockaddr_in server_addr;
char recvBuff[BUFFERSIZE];
char sendBuff[BUFFERSIZE];
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd < 0){
cout << "Failed to create Socket" << endl;
return -1;
}
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons(PORTNUM);
if(connect(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr) ) <0){
cout << "Failed to connect" << endl;
}
while(1){
if((connfd = read(sockfd, recvBuff, sizeof(recvBuff)-1)) > 0){
recvBuff[connfd] = 0;
if(fputs(recvBuff, stdout) == EOF){
cout << "Error" << endl;
}
cout << endl;
}
cout << "input: " << endl;
do{
cin.getline(sendBuff, BUFFERSIZE);
cout<< "input: " << sendBuff << endl;
if(strlen(sendBuff) > 0){
write(sockfd, sendBuff, strlen(sendBuff));
//send(sockfd, sendBuff, BUFFERSIZE, 0);
cout << "sent" << endl;
}
}while (*sendBuff != 42);
sleep(1);
}
}
Please tell me what the cause of the problem is, and how to fix it.
Thank you.

Socket consistently disconnecting C++

I have a client and server set up to talk to each other. But every time I try to echo back to the client the socket seems to have disconnected. Much of the code is adapted from a sockets tutorial over at yolinux. Also, I'm running this remotely over ssh.
Client:
#include <cerrno>
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <sys/socket.h>
#include <netdb.h>
#include <sys/select.h>
#include <sys/time.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <errno.h>
#include <iostream>
#include <cstdlib>
#include <stdlib.h>
#include <strings.h>
#include <string.h>
#include <string>
#include <sstream>
using namespace std;
main(int argc, char *argv[])
{
if (argc != 3) {
cout << "exiting\n";
exit(EXIT_FAILURE);
}
struct sockaddr_in remoteSocketInfo;
struct hostent *hPtr;
int socketHandle;
char *remoteHost = argv[1];
int portNumber = atoi(argv[2]);
cout << "Welcome!\n";
// create socket
if ((socketHandle = socket(AF_INET, SOCK_STREAM, IPPROTO_IP)) < 0)
{
cout << "Socket creation failed.\n";
close(socketHandle);
exit(EXIT_FAILURE);
}
cout << "Socket created!\n";
bzero(&remoteSocketInfo, sizeof(sockaddr_in)); // Clear structure memory
if ((hPtr = gethostbyname(remoteHost)) == NULL)
{
cerr << "System DN name resolution not configured properly.\n";
cerr << "Error number: " << ECONNREFUSED << endl;
exit(EXIT_FAILURE);
}
// Load system information for remote socket server into socket data structures
memcpy((char*)&remoteSocketInfo.sin_addr, hPtr->h_addr, hPtr->h_length);
remoteSocketInfo.sin_family = AF_INET;
remoteSocketInfo.sin_port = htons((u_short)portNumber); // set port number
if (connect(socketHandle, (struct sockaddr *)&remoteSocketInfo, sizeof(sockaddr_in)) < 0) {
cout << "connection failed\n";
close(socketHandle);
exit(EXIT_FAILURE);
}
cout << "Connected!\n";
string input;
int message;
while (1) {
cout << "Please indicate rotation amount:";
cin >> input;
if (input == "exit") {
close(socketHandle);
break;
}
char buf[input.length()+1];
const char *conv_input = input.c_str();
strcpy(buf, conv_input);
int bytes_sent = 0;
if ( (bytes_sent = send(socketHandle, buf, strlen(buf)+1, 0)) < 0) {
char buffer[256];
char * errorMessage = strerror_r( errno, buffer, 256);
cout << errorMessage << endl;
close(socketHandle);
exit(EXIT_FAILURE);
}
cout << "bytes sent: " << bytes_sent << endl;
int rc;
char buf2[input.length()+1];
rc = recv(socketHandle, buf2, strlen(buf)+1, 0);
buf[rc] = (char)NULL; // Null terminate string
cout << "received: " << buf2 << endl;
cout << "bytes received: " << rc << endl;
}
close(socketHandle);
}
Server:
#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdlib.h>
#include <strings.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <cstring>
#define MAXHOSTNAME 256
using namespace std;
main(int argc, char *argv[])
{
if (argc != 2) {
cout << "not enough arguments, ex: ./CaesarCipherServer 9876\n";
exit(EXIT_FAILURE);
}
struct sockaddr_in socketInfo;
char sysHost[MAXHOSTNAME+1]; // Hostname of this computer we're running on
struct hostent *hPtr;
int portNumber = atoi(argv[1]);
int sock;
bzero(&socketInfo, sizeof(sockaddr_in)); // Clear structure memory
// Get system information
gethostname(sysHost, MAXHOSTNAME); // Get this computer's hostname
if ((hPtr = gethostbyname(sysHost)) == NULL)
{
cerr << "System hostname misconfigured." << endl;
exit(EXIT_FAILURE);
}
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
close(sock);
exit(EXIT_FAILURE);
}
// Load system info into socket data structures
socketInfo.sin_family = AF_INET;
socketInfo.sin_addr.s_addr = htonl(INADDR_ANY); // Use any addr available
socketInfo.sin_port = htons(portNumber); // Set port number
// Bind the socket to a local socket address
if (bind(sock, (struct sockaddr *) &socketInfo, sizeof(socketInfo)) < 0)
{
close(sock);
perror("bind");
exit(EXIT_FAILURE);
}
cout << "listening for initial connection \n";
listen(sock, 1);
int sockConn;
if ((sockConn = accept(sock, NULL, NULL)) < 0)
{
exit(EXIT_FAILURE);
} else {
cout << "connection accepted!\n";
}
int rc = 0;
char buf[512];
cout << "about to receive message... \n";
// rc is number of chars returned
rc = recv(sockConn, buf, 512, 0);
buf[rc] = (char)NULL; // Null terminate string
cout << "received: " << buf << endl;
cout << "rc: " << rc << endl;
int bytes_sent;
if ((bytes_sent = send(sock, buf, rc, MSG_NOSIGNAL)) < 0) {
cout << "error sending\n";
close(sock);
exit(EXIT_FAILURE);
}
cout << "bytes sent: " << bytes_sent << endl;
close(sock);
}
Client Output:
./CaesarCipherClient cs-ssh 9876
Welcome!
Socket created!
socket handle : 3
Connected!
Please indicate rotation amount:5
bytes sent: 2
received:
bytes received: 0
Please indicate rotation amount:
Server Output:
./CaesarCipherServer 9876
listening for initial connection
connection accepted!
about to receive message...
received: 5
rc: 2
error sending
If the MSG_NOSIGNAL flag isn't specified, the server crashes at send(), which means the socket has disconnected at the other end. Why would the socket consistently disconnect after a send()/recv() pair?
I apologize for any poor readability/style/pure stupidity in my submission.
Thank you for your help!
In your server, you are using:
if ((bytes_sent = send(sock, buf, rc, MSG_NOSIGNAL)) < 0) {
cout << "error sending\n";
close(sock);
exit(EXIT_FAILURE);
}
Here, sock is the listening socket, not the accepted client socket. You need to replace sock with sockCon instead (which you are using in your recv() function call, and that is working).

bind socket fails with errno 88 [duplicate]

This question already has an answer here:
Bind return error 88
(1 answer)
Closed 5 years ago.
I was searching for an answer for my issue though nothing relevant came up.
I'm writing a very simple code for running a server on a virtual machine (VBOX) running ubuntu 14.04.
I turned off my firewall and my anti-virus program (read that it might be related)
I rechecked (and looked for different ports) that the port is not in use but keep on receiving return value of -1 to the bind() function with errno 88 (socket operation on non-socket).
I'm running the server on port 7777.
Also tried running this code on my host
Can someone suggest what I am doing wrong?
p.s also checked the code with valgrind for memory leaks but it looks fine.
the code is as follows:
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <iostream>
#include <fstream>
#include <strings.h>
#include <stdlib.h>
#include <string>
#include <pthread.h>
#include <errno.h>
using namespace std;
#define NUM_OF_THREADS 3
static int connFd;
void *task1(void *);
/*
*
*/
int main(int argc, char** argv) {
int pid, portNo, listenFd;
socklen_t len; // store the size of the address
bool loop = false;
struct sockaddr_in svrAdd, clntAdd;
pthread_t threadArr[NUM_OF_THREADS];
if (argc < 2){
cerr << "ERROR: ./server <port>" << endl;
return 0;
}
portNo = atoi(argv[1]); // TODO verify the port is between 1024 and 65535
//Create the socket
if (listenFd = socket(AF_INET, SOCK_STREAM, 0) < 0){
cerr << "ERROR: cannot open socket." << endl;
return 0;
}
bzero((char*)&svrAdd, sizeof(svrAdd));
svrAdd.sin_family = AF_INET;
svrAdd.sin_addr.s_addr = INADDR_ANY;
svrAdd.sin_port = htons(portNo);
cout << "port number is : " << portNo << endl;
//bind socket
int bound = bind(listenFd, (struct sockaddr *)&svrAdd, sizeof(svrAdd));
if ( bound < 0 ){
cerr << "ERROR: cannot bind, error number: " << errno << endl;
return 0;
}
listen(listenFd, 5);
len = sizeof(clntAdd);
int noTread = 0;
while(noTread < 3){
cout << "Listening..." << endl;
if (connFd = accept(listenFd, (struct sockaddr*)&clntAdd, &len)<0){
cerr << "ERROR: cannot accept connection" << endl;
return 0;
}
else{
cout << "Connection successful" << endl;
}
pthread_create(&threadArr[noTread], NULL, task1, NULL);
noTread++;
}
for (int i=0; i < 3; i++){
pthread_join(threadArr[i], NULL);
}
/*int sockfd, newsockfd, portno, clilen, n;
char buffer[256];
struct sockaddr_in serv_addr, cli_addr;
if (argc < 2){
fprintf(stderr, "ERROR, no port provided");
exit(1);
}
if(sockfd = socket(AF_INET, SOCK_STREAM, 0) < 0){
error("ERROR opening socket");
}
bzero((char *) &serv_addr, sizeof(serv_addr));
portno = atoi(argv[1]);
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(portno);
serv_addr.sin_addr.s_addr - INADDR_ANY;
if(bind(sockfd, (struct sockaddr*)&))*/
return 0;
}
void *task1(void *dummyPt){
cout << "Thread number: " << pthread_self() << endl;
char test[300];
bzero(test, 301);
bool loop = false;
while (!false){
bzero(test, 301);
read(connFd, test, 300);
string tester(test);
cout << "\n\t\t TESTER = " << tester << endl;
if(tester == "exit"){
break;
}
}
cout << "\n Closing thread and conn" << endl;
close(connFd);
}
The output of the execution:
ERROR: cannot bind, error number: 88
port number is : 7777
RUN SUCCESSFUL (total time: 162ms)
Please help,
Thanks.
if (listenFd = socket(AF_INET, SOCK_STREAM, 0) < 0){
Precedence problem. The result of this condition is to assign zero or 1 to listenFd. Try this:
if ((listenFd = socket(AF_INET, SOCK_STREAM, 0)) < 0){