Reputation: 13
I have to create a TCP/IP server/client socket program where both the server and client have to be in the same .c file. Below is my code where if there are no command line arguments entered then a server is created and waits for another process to initiate a connection. If there's one command line argument entered (IP address) then the process takes on a client role and connects to the other process executing at the specificed IP address. I'm just using localhost.
When I run the program with an ip address (./game localhost) I get
~/Desktop/a5 20 $ ./game localhost
ERROR connecting: Connection refused
When I run the program with no ip address (./game) I get a segfault
~/Desktop/a5 19 $ ./game
Segmentation fault (core dumped)
Any help as to what I'm doing wrong would be greatly appreciated!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>
#define h_addr h_addr_list[0]
void error(char *msg) {
perror(msg);
exit(1);
}
int main(int argc, char *argv[]) {
int sockfd, newsockfd, portno, clilen, sockfd2, portno2, n, n2;
char buffer[256];
char buffer2[256];
struct sockaddr_in serv_addr, cli_addr, serv_addr2;
struct hostent *server;
portno = 4547;
if (argc == 1) {
sockfd2 = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd2 < 0) {
error("ERROR opening socket");
}
server = gethostbyname(argv[1]);
if (server == NULL) {
fprintf(stderr,"ERROR, no such host\n");
exit(0);
}
bzero((char *) &serv_addr2, sizeof(serv_addr2));
serv_addr2.sin_family = AF_INET;
bcopy((char *)server->h_addr,(char *)&serv_addr2.sin_addr.s_addr,server->h_length);
serv_addr2.sin_port = htons(portno);
if (connect(sockfd2,(struct sockaddr *)&serv_addr2,sizeof(serv_addr2)) < 0) {
error("ERROR connecting");
}
printf("Please enter the message: ");
bzero(buffer2,256);
fgets(buffer2,255,stdin);
n2 = write(sockfd2,buffer2,strlen(buffer2));
if (n2 < 0) {
error("ERROR writing to socket");
}
printf("%s\n",buffer2);
}
else if (argc == 0) {
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
error("ERROR opening socket");
}
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(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");
}
}
return 0;
}
Upvotes: 0
Views: 98
Reputation: 15229
Usually argv[0]
is a pointer to the command the executable was executed with. That means argc
is always at least 1.
Increment the checks for argc
like
if (argc == 1)
by one, so the above if
clause changes to
if (argc == 2)
This is the reason for your segmentation fault because argv[1]
passed to gethostbyname
doesn't point to an argument if argc == 1
but contains NULL
as the standard mandates that argv[argc] == NULL
.
Note that this goes for the common systems. It is not defined in the C standard but in the POSIX standard, AFAIK.
Upvotes: 2