Segmentation fault - sending object over server to client - c++

I am trying to create a client server application in linux. Server sends object to client but client write Segmentation fault. Here is the code.
Snake is class where is two-dimensional array.
Client send message "p" and server is creating object witch will be send to client.
Server side:
int main(int argc, char *argv[])
{
int sockfd, newsockfd;
socklen_t cli_len;
struct sockaddr_in serv_addr, cli_addr;
int n;
char buffer[256];
if (argc < 2)
{
fprintf(stderr,"usage %s port\n", argv[0]);
return 1;
}
bzero((char*)&serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(atoi(argv[1]));
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
{
perror("Error creating socket");
return 1;
}
if (bind(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0)
{
perror("Error binding socket address");
return 2;
}
while(sockfd){
listen(sockfd, 5);
cli_len = sizeof(cli_addr);
newsockfd = accept(sockfd, (struct sockaddr*)&cli_addr, &cli_len);
if (newsockfd < 0)
{
perror("ERROR on accept");
return 3;
}
bzero(buffer,256);
n = read(newsockfd, buffer, 255);
if (n < 0)
{
perror("Error reading from socket");
return 4;
}
// if client send 'p'
if(*buffer == 'p' ){
Snake *snake = new Snake();
send(newsockfd,reinterpret_cast<const char*>(&snake), sizeof(snake),0);
}
}
//printf("Here is the message: %s\n", buffer);
const char* msg = "I got your message";
n = write(newsockfd, msg, strlen(msg)+1);
if (n < 0)
{
perror("Error writing to socket");
return 5;
}
close(newsockfd);
close(sockfd);
}
Client side:
int main(int argc, char *argv[])
{
int sockfd = 0,newsockfd, n;
struct sockaddr_in serv_addr;
struct hostent* server;
socklen_t cli_len, serv_len;
char buffer[999999];
struct sockaddr_in cli_addr;
if (argc < 3)
{
fprintf(stderr,"usage %s hostname port\n", argv[0]);
return 1;
}
server = gethostbyname(argv[1]);
if (server == NULL)
{
fprintf(stderr, "Error, no such host\n");
return 2;
}
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(atoi(argv[2]));
//while(sockfd >= 0){
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
{
perror("Error creating socket");
return 3;
}
if(connect(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0)
{
perror("Error connecting to socket");
return 4;
}
printf("Please enter a message: ");
bzero(buffer,256);
fgets(buffer, 255, stdin);
n = write(sockfd, buffer, strlen(buffer));
if (n < 0)
{
perror("Error writing to socket");
return 5;
}
Snake *snake ;
recv(sockfd,reinterpret_cast<char*>(&snake), sizeof(snake),0);
if (n < 0)
{
perror("Error reading from socket");
return 6;
}
printf("%s\n",buffer);
close(sockfd);
close(newsockfd);
return 0;
}
Thank you for your answers.

On the client side
Snake *snake ;
recv(sockfd,reinterpret_cast<char*>(&snake), sizeof(snake),0);
tries to read into a Snake, but you haven't created any. So the uninitialized pointer gives you the segmentation fault.
Also, sizeof(snake) is the size of a pointer (like 4 bytes), not the size of the object pointed to. This occurs both in the server and in the client.

Related

error in send data to server

Why when run the program and send data to server return this errorrecv failed: Transport endpoint is not connected or don't show server accepted just show the message of send data function in client
server.cpp:
int main() {
char packet[30];
char buffer[20] = "I got your message";
int conn_sock, comm_sock, n, m;
struct sockaddr_in server_addr, client_addr;
if ((conn_sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("Couldn't create socket");
exit(1);
}
cout << "Already create socket!!!\n" << endl;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(0);
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
memset(&server_addr, 0, sizeof(server_addr));
if (bind(conn_sock, (struct sockaddr *) &server_addr, sizeof(server_addr))
== -1) {
perror("couldn't bind");
exit(1);
}
if (listen(conn_sock, 10) == -1) {
perror("couldn't listen");
exit(1);
}
cout << "Listening For Connection...\r" << endl;
socklen_t len = sizeof(server_addr);
if (getsockname(conn_sock, (struct sockaddr *) &server_addr, &len) == -1)
perror("getsockname");
else
printf("port number %d\n", ntohs(server_addr.sin_port));
while (1) {
memset(&client_addr, 0, sizeof(client_addr));
if ((comm_sock = accept(conn_sock, (struct sockaddr *) &client_addr,
(socklen_t *) &client_addr)) == -1) {
perror("couldn't accept\n");
continue;
}
cout << "accepted" << endl;
bzero(packet, 10);
m = recv(conn_sock, packet, 10, 0);
if (m < 0) {
perror("recv failed");
exit(1);
}
cout<<"recieved"<<endl;
/* Write a response to the client */
n = send(conn_sock, buffer, sizeof(buffer), 0);
if (n < 0) {
perror("ERROR send to client");
exit(1);
}
close(n);
close(m);
close(comm_sock);
}
close(conn_sock);
return 0;
}
cilent.cpp:
#define MYPORT 51833
namespace personalization {
bool client::conn() {
//create socket if it is not already created
if (sock == -1) {
//Create socket
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock == -1) {
perror("Could not create socket");
}
cout << "Socket created" << endl;
}
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(MYPORT);
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
if (connect(sock , (struct sockaddr *)&server_addr , sizeof(server_addr)) < 0)
{
perror("connect failed. Error");
return false;
}
cout<<"Connected\n";
return true;
close(sock);
}
bool client::send_data() {
//Send some data
if( send(sock , packet , sizeof( packet ) , 0) < 0)
{
perror("Send failed");
return false;
}
cout<<"Data send\n";
return true;
close(sock);
}
bool client::rec_data() {
char buffer[20];
string reply;
//Receive a echo from the server
if (recv(sock, buffer, sizeof(buffer), 0) < 0) {
perror("receive failed");
return false;
}
reply = buffer;
return true;
close(sock);
}
client::client() {
// TODO Auto-generated constructor stub
sock=-1;
}
output is:
server:Already create socket!!!
Listening For Connection...
port number 51833
client: Socket created
Connected
Data send
receive failed: Connection reset by peer
or:
server:Already create socket!!!
Listening For Connection...
port number 51833
client:Socket created
Connected
Data send
srver:accepted
recv failed: Transport endpoint is not connected
In the server's recv and send calls, you need to pass the socket returned from accept.
So instead of
m = recv(conn_sock, packet, 10, 0);
do
m = recv(comm_sock, packet, 10, 0);
Same goes for the send call.
Also, don't call close on n and m, that is to say remove these two lines of code:
close(n);
close(m);
EDIT: Sorry, while I'm at it, this is probably not what you intended in the client's send_data and rec_data:
return true;
close(sock);

FIXED: C++ server/client program: "Connection refused"

I'm writing a simple program to transfer files from server to client (both on the same computer for now). Using "telnet 127.0.0.1 [port]", I can succesfully get the file from the server, but when I run the client, the server refuses connection. I suspect that the client is trying to connect to the wrong address, but I'm not sure. I also added some GDB test output if it helps.
Server: "./server 0 4100 bigfile 100 0.01"
int main(int argc, char* argv[])
{
int sockfd;
if(!(sockfd = socket(AF_INET, SOCK_STREAM, 0))) {
error("Failed to create socket");
}
struct sockaddr_in serv_addr, cl_addr;
bzero((void*) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(atoi(argv[2]));
if(bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
error("Failed to bind");
}
listen(sockfd, 10);
int fd = open(argv[3], O_RDONLY);
int bufsize = atoi(argv[4]);
int packet_period = atoi(argv[5]);
size_t cl_addr_len = sizeof(cl_addr);
char *buf = new char[bufsize];
while(true) {
int sd;
cout << "waiting for client..." << endl;
if(!(sd = accept(sockfd, (struct sockaddr *) &cl_addr, (socklen_t*) &cl_addr_len))) {
error("Failed to acccept");
}
cout << "Accepted client connection" << endl;
lseek(fd, 0, SEEK_SET);
while(int n = read(fd, buf, bufsize)) {
cout << "Transferring " << buf << endl;
usleep(100000);
write(sd, buf, n);
}
}
}
Client: "./client 0 127.0.0.1 4100 bigfile stats"
int main(int argc, char *argv[])
{
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
error("Failed to open socket");
}
struct sockaddr_in serv_addr;
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = inet_addr(argv[2]);
serv_addr.sin_port = htons(atoi(argv[3])); // I tried both htons and htonl
if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0) {
error("Failed to connect");
}
int n;
char buf[256];
int fd = open(argv[4], O_RDONLY);
while((n = read(sockfd, buf, 256)) > 0) {
printf("Received: %s\n", buf);
write(fd, buf, n);
}
close(fd);
close(sockfd);
return 0;
}
GDB Output:
(gdb) r
Starting program: [...]/client 0 127.0.0.1 4100 bigfile stats
Breakpoint 1, main (argc=6, argv=0x7fffffffde68) at client.cpp:31
31 if (connect(sockfd,(struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
(gdb) p serv_addr
$1 = {sin_family = 2, sin_port = 0, sin_addr = {s_addr = 16777343},
sin_zero = "\000\000\000\000\000\000\000"}
{sin_family = 2, sin_port = 0, sin_addr = {s_addr = 16777343}, sin_zero = "\000\000\000\000\000\000\000"}
So sin_port is wrong: it shouldn't be zero. The code that sets it is:
serv_addr.sin_port = htonl(atoi(argv[3]));
The problem is here. It should be
serv_addr.sin_port = htons(atoi(argv[3]));
Not today's problem but
printf("Received: %s\n", buf);
should be
printf("Received: %.*s\n", n, buf);

Error connecting to server by proxy server in c++ socket programming

The code for connection :
cout << "connecting1\n";
WSADATA wsadata;
int iResult = WSAStartup (MAKEWORD(2,2), &wsadata );
if (iResult !=NO_ERROR )
printf("\nmyERROR at WSAStartup()\n");
int sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock == -1) {
perror("error opening socket"); return -1;
}
struct sockaddr_in sin;
sin.sin_port = htons(port);
sin.sin_addr.s_addr = inet_addr(host.c_str());
sin.sin_family = AF_INET;
if (connect(sock, (struct sockaddr *)&sin, sizeof(sin)) == -1) {
perror("error connecting to host"); return -1;
}
const int query_len = query.length() + 1; // trailing '\0'
if (send(sock, query.c_str(), query_len, 0) != query_len) {
perror("error sending query"); return -1;
}
const int buf_size = 1024 * 1024;
while (true) {
std::vector<char> buf(buf_size, '\0');
const int recv_len = recv(sock, &buf[0], buf_size - 1, 0);
if (recv_len == -1) {
perror("error receiving response"); return -1;
} else if (recv_len == 0) {
std::cout << std::endl; break;
} else {
std::cout << &buf[0];
fprintf(fp, "%s", &buf[0]);
}
}
In wifi without proxy it works fine, but when we use proxy server, net can be accessed in chrome, but the above code prints
connecting1
error connecting to host
What is the problem ?

C++ send file and text via socket

Im trying to send a image using socket but I have to send the file name as well. Im using a code that i send the file but when I send the file name i receive some strange characters in client.
Client:
#define PORT 20000
#define LENGTH 512
int main(int argc, char *argv[]){
int sockfd;
int nsockfd;
char revbuf[LENGTH];
struct sockaddr_in remote_addr;
/* Get the Socket file descriptor */
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
fprintf(stderr, "ERROR: Failed to obtain Socket Descriptor! (errno = %d)\n",errno);
exit(1);
}
/* Fill the socket address struct */
remote_addr.sin_family = AF_INET;
remote_addr.sin_port = htons(PORT);
inet_pton(AF_INET, "127.0.0.1", &remote_addr.sin_addr);
bzero(&(remote_addr.sin_zero), 8);
/* Try to connect the remote */
if (connect(sockfd, (struct sockaddr *)&remote_addr, sizeof(struct sockaddr)) == -1)
{
fprintf(stderr, "ERROR: Failed to connect to the host! (errno = %d)\n",errno);
exit(1);
}
else
printf("[Client] Connected to server at port %d...ok!\n", PORT);
/* Send File to Server */
//if(!fork())
//{
char* fs_name = "house.jpg";
char sdbuf[LENGTH];
char buffer[256];
int n;
fgets(buffer,255,stdin);
bzero(buffer,256);
n = write(sockfd,buffer, strlen(buffer));
if(n<0) printf("Error: sending filename");
printf("[Client] Sending %s to the Server... ", fs_name);
FILE *fs = fopen(fs_name, "r");
if(fs == NULL)
{
printf("ERROR: File %s not found.\n", fs_name);
exit(1);
}
bzero(sdbuf, LENGTH);
int fs_block_sz;
while((fs_block_sz = fread(sdbuf, sizeof(char), LENGTH, fs)) > 0)
{
if(send(sockfd, sdbuf, fs_block_sz, 0) < 0)
{
fprintf(stderr, "ERROR: Failed to send file %s. (errno = %d)\n", fs_name, errno);
break;
}
bzero(sdbuf, LENGTH);
}
printf("Ok File %s from Client was Sent!\n", fs_name);
//}
close (sockfd);
printf("[Client] Connection lost.\n");
return (0);
}
Part of client that sends the text:
char buffer[256];
int n;
fgets(buffer,255,stdin);
bzero(buffer,256);
n = write(sockfd,buffer, strlen(buffer));
if(n<0) printf("Error: sending filename");
Server:
#define PORT 20000
#define BACKLOG 5
#define LENGTH 512
int main ()
{
int sockfd;
int nsockfd;
int num;
int sin_size;
struct sockaddr_in addr_local; /* client addr */
struct sockaddr_in addr_remote; /* server addr */
char revbuf[LENGTH];
/* Get the Socket file descriptor */
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1 )
{
fprintf(stderr, "ERROR: Failed to obtain Socket Descriptor. (errno = %d)\n", errno);
exit(1);
}
else
printf("[Server] Obtaining socket descriptor successfully.\n");
/* Fill the client socket address struct */
addr_local.sin_family = AF_INET; // Protocol Family
addr_local.sin_port = htons(PORT); // Port number
addr_local.sin_addr.s_addr = INADDR_ANY; // AutoFill local address
bzero(&(addr_local.sin_zero), 8); // Flush the rest of struct
/* Bind a special Port */
if( bind(sockfd, (struct sockaddr*)&addr_local, sizeof(struct sockaddr)) == -1 )
{
fprintf(stderr, "ERROR: Failed to bind Port. (errno = %d)\n", errno);
exit(1);
}
else
printf("[Server] Binded tcp port %d in addr 127.0.0.1 sucessfully.\n",PORT);
/* Listen remote connect/calling */
if(listen(sockfd,BACKLOG) == -1)
{
fprintf(stderr, "ERROR: Failed to listen Port. (errno = %d)\n", errno);
exit(1);
}
else
printf ("[Server] Listening the port %d successfully.\n", PORT);
int success = 0;
while(success == 0)
{
sin_size = sizeof(struct sockaddr_in);
/* Wait a connection, and obtain a new socket file despriptor for single connection */
if ((nsockfd = accept(sockfd, (struct sockaddr *)&addr_remote, &sin_size)) == -1)
{
fprintf(stderr, "ERROR: Obtaining new Socket Despcritor. (errno = %d)\n", errno);
exit(1);
}
else
printf("[Server] Server has got connected from %s.\n", inet_ntoa(addr_remote.sin_addr));
char buffer[256];
bzero(buffer,256);
int n = 0;
n = read(nsockfd, buffer, 255);
if (n < 0) error("ERROR reading from socket");
printf("msg: %s\n",buffer);
/*Receive File from Client */
char* fr_name = "/house.jpg";
FILE *fr = fopen(fr_name, "a");
if(fr == NULL)
printf("File %s Cannot be opened file on server.\n", fr_name);
else
{
bzero(revbuf, LENGTH);
int fr_block_sz = 0;
while((fr_block_sz = recv(nsockfd, revbuf, LENGTH, 0)) > 0)
{
int write_sz = fwrite(revbuf, sizeof(char), fr_block_sz, fr);
if(write_sz < fr_block_sz)
{
error("File write failed on server.\n");
}
bzero(revbuf, LENGTH);
if (fr_block_sz == 0 || fr_block_sz != 512)
{
break;
}
}
if(fr_block_sz < 0)
{
if (errno == EAGAIN)
{
printf("recv() timed out.\n");
}
else
{
fprintf(stderr, "recv() failed due to errno = %d\n", errno);
exit(1);
}
}
printf("Ok received from client!\n");
fclose(fr);
}
}
}
Part of server that receive the text:
char buffer[256];
bzero(buffer,256);
int n = 0;
n = read(nsockfd, buffer, 255);
if (n < 0) error("ERROR reading from socket");
printf("msg: %s\n",buffer);
Need some help with that. Thanks...
In this code in your client:
char buffer[256];
int n;
fgets(buffer,255,stdin);
bzero(buffer,256);
n = write(sockfd,buffer, strlen(buffer));
It looks like you are trying to read the file name from the stdin and send it on the sockfd. But. you zero out the buffer before you send it.

Having issues with chat program over TCP using C++ on Ubuntu 12.10

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.