if (strcmp(buffer,"change work")==0)
{
close(newsockfd); /*closing the old port*/
close(sockfd);
printf("Changing port to 51717....\n");
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
bzero((char *) &serv_addr, sizeof(serv_addr));
portno = atoi("51717");
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) /*binding with the new port*/
error("ERROR on binding");
listen(sockfd,5);
clilen = sizeof(cli_addr);
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
if (newsockfd < 0)
error("ERROR on accept");
printf("port changed\n");
bzero(buffer,256);
n = read(newsockfd,buffer,255);
if (n < 0) error("ERROR reading from socket");
printf("Here is the message: %s\n",buffer);
n = write(newsockfd,"I got your message",18);
if (n < 0) error("ERROR writing to socket");
}
else
{
printf("Here is the message: %s\n",buffer);
n = write(newsockfd,"I got your message",18);
if (n < 0) error("ERROR writing to socket");
close(newsockfd);
close(sockfd);
}
In the above code when the condition is satisfied, both the codes are being executed instead of code1. This loop is not working properly. what may be the reason???
I want to focus on if part.
Two approaches to solving this:
a). Step in a debugger, you're quite likely to see that your code isn't quite as you think.
b). replace your complex code with a simple construct.
if (strcmp(buffer,"change work")!=0)
{ printf("yes") }
else
{ printf("no"); }
You will see that this works just fine, then make incremental changes to turn it back into your real code, at some point you'll go "aha".
Edited in light of your last comment:
My guess is that buffer does not contain exactly "change work" but perhaps also a newline character or other such delimiter. You would probably be benefit from adding diagnostic trace statements to show the buffer contents, use java.util.logging or log4j.
Related
EDIT: Minimal, Complete, and Verifiable example is in comment lower and the code actually works, problem was in different area. Sorry for bad posting, I cannot delete it now.
I know, that there are some pages about this already, but I really tried everything and nothing works. Im having this error all the time and my code looks like this:
int server_socket, new_socket;
struct sockaddr_in server;
bzero((char *) &server, sizeof(server));
server_socket = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0);
if(server_socket < 0) error("ERROR opening socket");
server.sin_family = AF_INET;
server.sin_addr.s_addr = htonl(INADDR_ANY);
server.sin_port = htons(port_number);
if(bind(server_socket, (struct sockaddr *) &server, sizeof(struct sockaddr_in)) < 0) error("ERROR on binding");
if(listen(server_socket, 5) < 0) error("Failed to listen for connections.");
while(1)
{
struct sockaddr_in client;
unsigned int client_len = sizeof(struct sockaddr_in);
bzero((char *) &client, client_len);
if((new_socket = accept(server_socket, (struct sockaddr *) &client, &client_len)) < 0)
{
if(errno == EAGAIN) continue;
else error("ERROR on accept");
}
if((pid = fork()) > 0)
{ // this is parent process
close(new_socket);
}
else if(pid == 0)
{ // this is a child process that will handle an incoming request
long_pid = (long) getpid(); // current child's PID
close(server_socket);
server_socket = -1; //closing parent socket
printf("A new connection accepted from blablabla, port %d by process %ld\n", port_number, long_pid);
// ---- doing some staff, running the program
EDIT: while((msg_size = read(new_socket, received_data, BUFFER_SIZE)) >0)
// ---- when Im done:
printf("closing newsock\n");
close(new_socket); // close the new socket
new_socket = -1;
exit(0);
}
}
else error("fork() failed");
}
// close the server
printf("closing an original socket\n");
close(server_socket); // close an original server socket
return 0;
}
I didnt have this problem before, when I was using nonblocking sockets. So problem is probably connected to them.
If I fill in the blanks to make this into a compilable example (please post an mcve next time)
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <stdio.h>
#include <strings.h>
#include <errno.h>
#include <arpa/inet.h>
#define port_number 2222
void error(char const *Msg)
{
perror(Msg);
exit(1);
}
int main()
{
pid_t pid; long long_pid;
int server_socket, new_socket;
struct sockaddr_in server;
bzero((char *) &server, sizeof(server));
server_socket = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0);
if(server_socket < 0) error("ERROR opening socket");
server.sin_family = AF_INET;
server.sin_addr.s_addr = htonl(INADDR_ANY);
server.sin_port = htons(port_number);
if(bind(server_socket, (struct sockaddr *) &server, sizeof(struct sockaddr_in)) < 0) error("ERROR on binding");
if(listen(server_socket, 5) < 0) error("Failed to listen for connections.");
while(1)
{
struct sockaddr_in client;
unsigned int client_len = sizeof(struct sockaddr_in);
bzero((char *) &client, client_len);
if((new_socket = accept(server_socket, (struct sockaddr *) &client, &client_len)) < 0)
{
if(errno == EAGAIN) continue;
else error("ERROR on accept");
}
if((pid = fork()) > 0)
{ // this is parent process
close(new_socket);
}
else if(pid == 0)
{ // this is a child process that will handle an incoming request
long_pid = (long) getpid(); // current child's PID
close(server_socket);
server_socket = -1; //closing parent socket
printf("A new connection accepted from blablabla, port %d by process %ld\n", port_number, long_pid);
// ---- doing some staff, running the program
// ---- when Im done:
printf("closing newsock\n");
close(new_socket); // close the new socket
new_socket = -1;
_exit(0);
}
else error("fork() failed");
}
// close the server
printf("closing an original socket\n");
close(server_socket); // close an original server socket
return 0;
}
it seems to work without any issues.
Obviously you're establishing the listening socket with error checks in the parent process and the parent process then isn't doing anything with the listening socket that closes it, so you shouldn't be getting that error from the parent process.
My guess is you're probably mistakenly continuing the loop in the child (in the part you're not showing).
I have a C++ application which receives 1 char and runs a function dependent on which char it has received. The problem is that the application stops as soon as it has received one message.
I need the application to start listening on the same port again after it has received a message but I haven't managed to do so. I tried looping it with a "while (true)" loop but I get errors.
It may also be worth noting that after the server has ran successfully it gives the message:
** * stack smashing detected ***: terminated
Aborted (core dumped)
And if I try to run the server again on the same port after it has successfully completed I get:
ERROR on binding: Address already in use
Significant code:
int main(int argc, char *argv[]) {
int sockfd, newsockfd, portno;
socklen_t clilen;
char buffer[1];
struct sockaddr_in serv_addr, cli_addr;
int n;
if (argc < 2) {
fprintf(stderr,"ERROR, no port provided\n");
exit(1);
}
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 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_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
if (bind(sockfd, (struct sockaddr *) &serv_addr,
sizeof(serv_addr)) < 0)
error("ERROR on binding");
listen(sockfd,5);
clilen = sizeof(cli_addr);
newsockfd = accept(sockfd,
(struct sockaddr *) &cli_addr,
&clilen);
if (newsockfd < 0)
error("ERROR on accept");
bzero(buffer,256);
n = read(newsockfd,buffer,255);
if (n < 0) error("ERROR reading from socket");
if (buffer[0] == '0') {
lamp();
}
else {
printf("No valid input from client.\n");
}
if (n < 0) error("ERROR writing to socket");
close(newsockfd);
close(sockfd);
return 0;
}
EDIT: I should've mentioned that I am very new to C++. Please give an example with your solution.
char buffer[1]; ... bzero(buffer,256);
Of course, after you've corrupted the whole stack it's understandable that other reasonable code is suddenly failing.
I'm developing a chat program over TCP to allow me to communicate between two machines over WAN. I'm pretty new to C++ (coming from Java) and am very new to TCP, so don't go too hard on me! (: I've looked around on a fair amount of tutorials and continue to find only Echo programs, nothing that can leave a connection open for an extended amount of time to allow a chat like function. My current code looks like this:
#include "ClientManager.h"
ClientManager::ClientManager() {
}
void ClientManager::connectCom(char* ipAdd) {
portno = atoi(PORT);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
server = gethostbyname(ipAdd);
if (server == NULL) {
fprintf(stderr,"ERROR, no such host\n");
exit(0);
}
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
bcopy((char *)server->h_addr,
(char *)&serv_addr.sin_addr.s_addr,
server->h_length);
serv_addr.sin_port = htons(portno);
if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)
error("ERROR connecting");
}
void ClientManager::message(std::string msg) {
// printf("Please enter the message: ");
char * buffer = new char[msg.size() + 1];
std::copy(msg.begin(), msg.end(), buffer);
buffer[msg.size()] = '\0';
// bzero(buffer,256);
// fgets(buffer,255,stdin);
n = write(sockfd,buffer,strlen(buffer));
if (n < 0)
error("ERROR writing to socket");
bzero(buffer,256);
n = read(sockfd,buffer,255);
if (n < 0)
error("ERROR reading from socket");
printf("%s\n",buffer);
bzero(buffer,256);
}
void ClientManager::closeCom() {
close(sockfd);
}
void ClientManager::error(const char *msg)
{
perror(msg);
exit(0);
}
and my server manager looks like this:
#include "ServerManager.h"
ServerManager::ServerManager() {
// int sockfd, portno, n;
// struct sockaddr_in serv_addr;
// struct hostent *server;
}
void ServerManager::openCom() {
char buffer[256];
struct sockaddr_in serv_addr, cli_addr;
int n;
socklen_t clilen;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
bzero((char *) &serv_addr, sizeof(serv_addr));
portno = atoi(PORT);
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
if (bind(sockfd, (struct sockaddr *) &serv_addr,
sizeof(serv_addr)) < 0)
error("ERROR on binding");
listen(sockfd,5);
clilen = sizeof(cli_addr);
newsockfd = accept(sockfd,
(struct sockaddr *) &cli_addr,
&clilen);
if (newsockfd < 0)
error("ERROR on accept");
bzero(buffer,256);
// n = read(newsockfd,buffer,255);
// if (n < 0) error("ERROR reading from socket");
// printf("Here is the message: %s\n",buffer);
// n = write(newsockfd,"I got your message",18);
// if (n < 0) error("ERROR writing to socket");
}
int ServerManager::readCom() {
bzero(buffer,256);
n = read(newsockfd,buffer,255);
if (n < 0) error("ERROR reading from socket");
printf("Here is the message: %s\n",buffer);
n = write(newsockfd,"I got your message",18);
if (n < 0) error("ERROR writing to socket");
if (buffer[0] == '0')
return 1;
return 0;
}
void ServerManager::closeCom() {
close(newsockfd);
close(sockfd);
}
void ServerManager::error(const char *msg) {
perror(msg);
exit(1);
}
Both of these classes are implemented by separate main functions who call the functions necessary. I know that the code itself is ok for sending a single message- its been doing that for awhile now. Its just when client calls more than one message() that I experience errors, specifically, a segmentation fault. This only happens on the second message, the first one is sent and received appropriately.
If anyone could help me out, it would be greatly appreciated. Thanks!
In ClientManager::message you forget to delete the buffer at the end of the method.
ALternatively, you should declare the buffer on the local stack as this:
char buffer[msg.size() + 1];
As such, the buffer will be automatically deallocated by the end of the call.
And reading later code, you better do:
char buffer[256];
I think the code for reading the server's reply causes buffer overrun if your msg.size() < serverReply.size, even if you think you have 256 characters (you simply didn't allocated them at method start) . Please take care to this buffer length declaration and later handling, as C++ would let you write beyond it's end, corrupting neighbouring variables and leading to segfaults.
I'm trying to build a client -> proxy server -> server application.
I need help with the proxy server, how do i make it send data to the server right now it can only communicate with the client.
Here is my codef or the proxy server, I modified it from an example. I'm new at this.
int main(int argc, char *argv[])
{
int sockfd, newsockfd, portno, pid;
socklen_t clilen;
struct sockaddr_in serv_addr, cli_addr;
if (argc < 2) {
fprintf(stderr,"ERROR, no port provided\n");
exit(1);
}
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 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_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
if (bind(sockfd, (struct sockaddr *) &serv_addr,
sizeof(serv_addr)) < 0)
error("ERROR on binding");
listen(sockfd,5);
clilen = sizeof(cli_addr);
while (1) {
newsockfd = accept(sockfd,
(struct sockaddr *) &cli_addr, &clilen);
if (newsockfd < 0)
error("ERROR on accept");
pid = fork();
if (pid < 0)
error("ERROR on fork");
if (pid == 0) {
close(sockfd);
dostuff(newsockfd);
exit(0);
}
else close(newsockfd);
} /* end of while */
close(sockfd);
return 0; /* we never get here */
}
/******** DOSTUFF() *********************
There is a separate instance of this function
for each connection. It handles all communication
once a connnection has been established.
*****************************************/
void dostuff (int sock)
{
int n, p;
char buffer[256];
char request;
FILE *file;
file = fopen("process.log","a+");
do
{
//here the proxy server receives data from the client
bzero(buffer,256);
p = read(sock,buffer,255);
if (n < 0) error("ERROR reading from socket");
printf("num: %s\n",buffer);
//here the proxy servers replies to the client.
n = write(sock,buffer,sizeof(buffer));
//here the process should send data to the server
//...codes i need help with...
if (n < 0) error("ERROR writing to socket");
fprintf(file,"%s\n",buffer); /*writes*/
}while(p != 0); //this runs the process +1 more than it should. wonder why?
fclose(file);
}
DoStuff() .... you can also check the comments I added.
Also how do I send a message to the client as soon as the client is connected to the server, something like a welcome client message? :)
note: the proxy server sends a GET request to a HTTP 1.1 server.
I would really appreciate it. Thanks :)
To connect to the server, you're going to have to call socket and then connect to get that socket connected to your real server from the proxy. See section 5 here:
http://beej.us/guide/bgnet/output/html/singlepage/bgnet.html
Additionally, check p instead of n 4 lines into your do-while loop in DoStuff().
I am sorry if the title is misleading. I cannot really think of a better one. Here is some simple socket program that I have:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/poll.h>
#include <iostream>
#define BACKLOG 10
void error(const char *msg)
{
perror(msg);
exit(1);
}
int main(int argc, char *argv[])
{
if (argc < 2) {
fprintf(stderr,"ERROR, no port provided\n");
exit(1);
}
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
struct sockaddr_in serv_addr;
bzero((char *) &serv_addr, sizeof(serv_addr));
int portno = atoi(argv[1]);
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
auto bindsuccess = bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
if (bindsuccess < 0)
error("ERROR on binding");
struct pollfd newPollFD[1];
newPollFD[0].fd = sockfd;
newPollFD[0].events = POLLIN;
char buffer[256];
bzero(buffer,256);
listen(sockfd, BACKLOG);
struct sockaddr_in cli_addr;
socklen_t clilen = sizeof(cli_addr);
int newsockfd;
int rv = poll(newPollFD, 1, -1);
if (rv == -1) {
error("Error occured in Poll");
}
else {
if (newPollFD[0].revents & POLLIN){
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
if (newsockfd < 0)
error("ERROR on accept");
int rwsuccess;
rwsuccess = read(newsockfd,buffer,255);
if (rwsuccess < 0)
error("ERROR reading from socket");
printf("Here is the message: %s\n",buffer);
rwsuccess = write(newsockfd,"I got your message \n",18);
if (rwsuccess < 0)
error("ERROR writing to socket");
}
}
close(newsockfd);
close(sockfd);
return 0;
}
If I execute this code with a port number, and then telnet to that port number, the server listens in, but as soon as I send my first message, the connection terminates. I want the sever to keep on listening and sending acknowledgement back as many times as I send message from telnet. How do I accomplish that?
Thanks in advance!
The continue is curiously extraneous, and causes the compilation to break. (It is now corrected in your edit.) But, you are missing a for loop. And, you should add a check if the read returns 0.
for (;;) {
int rwsuccess;
rwsuccess = read(newsockfd,buffer,255);
if (rwsuccess < 0)
error("ERROR reading from socket");
if (rwsuccess == 0) break;
printf("Here is the message: %s\n",buffer);
rwsuccess = write(newsockfd,"I got your message \n",18);
if (rwsuccess < 0)
error("ERROR writing to socket");
}