I am writing a C program that creates a server side program that sends the message "From Server" to the client program. However, I have problem with the client. Error segmentation fault (core dumped) on the line strcpy(hostname,argv[1]);
(I have marked on the client code).
Following are my codes:
Server:
/* Server program */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
int main(int argc, char* argv[])
{
/* Declaration of sock and newsock as integer variables to handle the socket */
int newsock,sock;
/* Declaration of ptr to store info about the host */
struct hostent* ptr;
/* Declaration of address as sockaddr_in structure to store info about Internet domain socket address */
struct sockaddr_in address;
/* Declaration of addrlen as integer to store the address length in internet domain */
int addrlen=sizeof(struct sockaddr_in);
/* Declaration of buf as string to handle the message */
char buf[100];
/* Declaration of msg as string to store the message to be sent */
char msg[50] ={"From server"};
/* Declaration of portnum as integer to store port number */
int portnum;
/* Declaration of qsize as integer to store queue size */
int qsize = 5;
/* Store port number from the command line argument */
portnum= atoi(argv[1]);
/* Create a socket */
printf("Creating socket");
sock=socket(AF_INET,SOCK_STREAM,0);
if(sock == -1)
{
printf("\nCannot create a socket\n");
return 0;
}
/* Store the values in the address structure */
address.sin_addr.s_addr=INADDR_ANY;
address.sin_port=htons(portnum);
address.sin_family=AF_INET;
/* Binding to local address */
printf("\nBinding to port\n");
if(bind(sock,(struct sockaddr*)&address,sizeof(address))== -1)
{
printf("\nCannot connect to host\n");
return 0;
}
/* Get local socket address */
getsockname(sock,(struct sockaddr*)&address,(socklen_t*)&addrlen);
printf("Opened socket:%d\nport:% d\n",sock, ntohs(address.sin_port));
printf("Server\n sin_family = %d\n sin_addr.s_addr = %d\n sin_port = %d\n",address.sin_family, address.sin_addr.s_addr, ntohs(address.sin_port));
/* Create a queue */
printf("Queue size %d:",qsize);
if(listen(sock,qsize) == -1)
{
printf("\nCannot listen\n");
return 0;
}
for(;;)
{
printf("\nWaiting for a connection\n");
/* Get the connected socket and accept the connection */
newsock=accept(sock,(struct sockaddr*)&address,(socklen_t*)&addrlen);
printf("\nGot a connection");
/* Send the message to the client */
strcpy(buf,msg);
printf("\nMessage sent to client:%s",buf);
write(newsock,buf,strlen(buf)+1);
/* Read read the message from the client */
read(newsock,buf,100);
printf("\nMessage received from client:%s",buf);
/* Terminate the connection */
if(close(newsock) == -1)
{
printf("\nCould not close socket\n");
return 0;
}
}
}
Client:
/* Client program */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
int main(int argc, char* argv[])
{
/* Declaration of sock as integer variable to handle the socket */
int sock;
/* Declaration of ptr to store info about the host*/
struct hostent* ptr;
/* Declaration of address as sockaddr_in structure to store info about Internet domain socket address */
struct sockaddr_in address;
/* Declaration of hostaddr as long to store the host address */
long hostaddr;
/* Declaration of buf and buf1 as string variables to handle the message */
char buf[100],buf1[100];
/* Declaration of amount as unsigned variable to store the number of bytes returned by read system call */
unsigned amount;
/* Declaration of hostname as string variable to store host name */
char hostname[255];
/* Declaration of portnum as integer to store port number */
int hostport;
/* Get the host name and port number from the command line arguments */
FAULT==================> strcpy(hostname,argv[1]);
hostport=atoi(argv[2]);
/* Create a socket */
printf("Making a socket");
sock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(sock == -1)
{
printf("\nCannot make a socket\n");
return 0;
}
/* Get IP address from host name */
ptr=gethostbyname(hostname);
/* Copy address into long */
memcpy(&hostaddr,ptr->h_addr,ptr->h_length);
/* Store the values in the address structure */
address.sin_addr.s_addr=hostaddr;
address.sin_port=htons(hostport);
address.sin_family=AF_INET;
/* Connect to the server */
printf("\nConnecting to %s on port %d",hostname,hostport);
if(connect(sock,(struct sockaddr*)&address,sizeof(address)) == -1)
{
printf("\nCould not connect to host\n");
return 0;
}
/* Read the message from the server */
amount=read(sock,buf,100);
printf("\nMessage received from server:%s",buf);
/* Write the message to the server */
strcpy(buf1,"From client");
write(sock,buf1,amount);
printf("\nMessage sent to server:%s",buf1);
/* Terminate the connection */
printf("\nClosing socket\n");
if(close(sock) == -1)
{
printf("\nCould not close socket\n");
return 0;
}
}
Following are the debugging session using gdb:
pc03@pc03:~$ cc sockc.c
pc03@pc03:~$ ./a.out localhost.localdomain 58733
Segmentation fault
pc03@pc03:~$ cc -g sockc.c
pc03@pc03:~$ ./a.out localhost.localdomain 58733
Segmentation fault
pc03@pc03:~$ gdb ./a.out
GNU gdb (GDB) 7.1-ubuntu
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i486-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/pc03/a.out...done.
(gdb) run
Starting program: /home/pc03/a.out
Program received signal SIGSEGV, Segmentation fault.
0x001a1210 in strcpy () from /lib/tls/i686/cmov/libc.so.6
(gdb) backtrace
#0 0x001a1210 in strcpy () from /lib/tls/i686/cmov/libc.so.6
#1 0x080486bf in main (argc=1, argv=0xbffff514) at sockc.c:38
(gdb) frame 1
#1 0x080486bf in main (argc=1, argv=0xbffff514) at sockc.c:38
38 strcpy(hostname,argv[1]);
(gdb) print hostname
$1 = "\277\022\000 \300\022\000\000\000\000\000\364\277\022\000\257\242\021\000\000\260\022\000\000\020\000\000\001\000\000\000\364\277\022\000\000\000\000\000X\363\377\277\177\246\021\000\260\312\022\000\230\375\377\267\001\000\000\000\001\000\000\000\000\000\000\000\240\362\377\277\364\277\022\000\000\000\000\000\000\000\000\000\060\363\377\277\200U\022\000\241\225\022\000|\212\022\000$\305\022\000\000\000\000\000\224\004\021\000\060\363\377\277\022\006\021\000P\363\377\277\324\002\021\000\002\000\000\000\064\003\021\000\a\000\000\000\220\246\023\000\020ii\rP\363\377\277\266\212\021\000\311\a\024\000\275\203\004\b\000\000\000\000$\203\004\bH\373\377\267\002\000\377\277 \346\021\000$\203\004\b\340\313\022\000\364\277\022\000\250\033\023\000\001\000\000\000\334\363\377\277f\220\021\000\200\364\377\277,1\021\000$\305\022\000\260\312\022", '\000' <repeats 21 times>"\260, \035\023\000܈\022"
(gdb) print argv
$2 = (char **) 0xbffff514
Appreciate for your help!
strcpy
with user input. You know how big your buffer is; use a function likestrncpy
instead. – cHao(gdb) run localhost.localdomain 58733
instead ofrun
please... Of course it will get a segfault on thestrcpy
, sinceargv[1]
is just crap (you didn't give any args). – nouneystdlib.h
;) PS: always compile with-Wall -Wextra
– polslinuxargc
to see if there were any command line arguments passed before referencing a possibly unintialisedargv[1]
. With basic errors like this and the above, there will probably be others lurking in there. – Weather Vanewrite(sock,buf1,amount);
in the client makes no sense. You have just put the fixed stringFrom client
inbuf1
(12 bytes including terminating NUL), butamount
contains the number of bytes just read from the server. – nobody