I am having some difficulty with this program. Right now I am running into a segmentation fault whenever anything is sent to the server. I also need to create a database to store those that enter the chat so that private messages can be sent to them but I have no idea how I should go about doing that. I believe the client is 99% of the way done, I just need to uncomment the one line (sending username to server for database). The server is where I am having difficulty I believe. I will provide the code.
How do I get rid of the segmentation fault? How should I create the database? How do I parse out the ".send" and the username?
Any help will be greatly appreciated. I have been working on this program for 3 weeks now and it is driving me crazy. I have never used C before only C++ and I have never done any socket programming. I also am not good with linux so if there are any commands you suggest me to use please explain them fully.
Client
Code:
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
extern int errno;
int main (int argc, char *argv[]){
char hname[255];
struct sockaddr_in sin;
struct sockaddr_in lin;
socklen_t sinlength;
socklen_t linlength;
struct hostent *ph;
int thesock;
int len;
long address;
char host[40];
char strinput[4096];
char strinput2[4096];
char buf[4096];
char x;
struct sockaddr_in to_addr;
struct sockaddr_in from;
socklen_t fromlen;
int i;
char username[20];
int pid;
char message;
int s;
if (argc != 3){
printf("Usage: ./a.out 172.21.24.1 port\n");
exit(1);
}
else{
strcpy(host, argv[1]);
}
if ((ph = gethostbyname (host)) == NULL){
switch (h_errno){
case HOST_NOT_FOUND:
fprintf(stderr, "%s: no such host %s\n", argv[0], host);
exit(1);
case TRY_AGAIN:
fprintf(stderr, "%s: host %s, try again later\n", argv[0], host);
exit(1);
case NO_RECOVERY:
fprintf(stderr, "%s: host %s DNS ERROR\n", argv[0], host);
exit(1);
case NO_ADDRESS:
fprintf(stderr, "%s: No IP address for %s\n", argv[0], host);
exit(1);
default:
fprintf(stderr, "Unknown error: %d\n", h_errno);
exit(1);
}
}
else {
memcpy ((char *) &sin.sin_addr, (char *) ph ->h_addr, ph -> h_length);
sin.sin_family = PF_INET;
}
i = gethostname(host, len);
sin.sin_port = atoi(argv[2]);
if ((s = socket (PF_INET, SOCK_DGRAM, 0)) < 0) {
perror ("socket");
exit(1);
}
lin.sin_family = PF_INET;
lin.sin_addr.s_addr = INADDR_ANY;
lin.sin_port = 0;
linlength = sizeof(lin);
if (bind(s, (struct sockaddr *) &lin, linlength) < 0){
perror ("bind");
exit(1);
}
if (getsockname(s, (struct sockaddr *) &lin, (socklen_t *) &linlength) < 0){
perror ("getsockname");
exit(1);
}
printf("What is your username?\n");
fgets(username, 20, stdin);
len = sizeof(hname);
sinlength = sizeof(struct sockaddr_in);
// sendto(s, username, strlen(username), 0, (struct sockaddr *) &sin, sizeof (struct sockaddr));
printf("\n");
printf("You can send any text that you want. There are 2 special commands.\n");
printf(".send <username> = send a private message to the username specified.\n");
printf("(DO NOT INCLUDE <> IN THE COMMAND\n");
printf(".quit = quit the program.\n");
printf("\n");
while(1){
pid = fork();
if (pid==0){
recvfrom(s, buf, 4095, 0, (struct sockaddr *) &from, &fromlen);
buf[message] = '\0';
printf("\n(%s, %d) said : ", inet_ntoa(from.sin_addr), ntohs(from.sin_port));
printf("%s", buf);
printf("\n");
printf("\n");
}
else {
char * strinput2;
fgets(strinput, 4095, stdin);
if (strinput2 = strstr (strinput, ".quit")){
sendto(s, strinput2, strlen(strinput2), 0, (struct sockaddr *) &sin, sizeof (struct sockaddr));
recvfrom(s, buf, 4095, 0, (struct sockaddr *) &from, &fromlen);
printf("The Client is now closing.\n");
close(s);
while ('\n' != getchar()){
getchar();
exit(1);
}
}
else{
sendto(s, strinput, strlen(strinput), 0, (struct sockaddr *) &sin, sizeof (struct sockaddr));
}
}
}
}
Server
Code:
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
extern int errno;
int main(int argc, char *argv[]){
const char * message;
int i;
int s;
int fd;
int len;
struct sockaddr_in sin;
int sinlength;
char buf[BUFSIZ];
int buflen;
char x;
char strinput[50];
struct sockaddr_in from;
socklen_t fromlen;
int pid;
int action;
if ((s = socket(PF_INET, SOCK_DGRAM,0)) < 0){
perror("Socket");
exit(1);
}
sin.sin_family = PF_INET;
sin.sin_addr.s_addr = INADDR_ANY;
sin.sin_port = 0;
sinlength = sizeof(sin);
if (bind(s, (struct sockaddr *) &sin, sinlength) < 0){
perror("bind");
exit(1);
}
if (getsockname(s, (struct sockaddr *) &sin, (socklen_t *) &sinlength) < 0){
perror("getsockname");
exit(1);
}
printf ("Socket is using port %d\n", sin.sin_port);
printf ("The Server is now running.\n");
while(1){
recvfrom(s, buf, buflen, 0, (struct sockaddr *) &from, &fromlen);
// buf[message] = '\0';
message==buf;
if (message = strstr(message, ".quit")){
char *reply;
reply = "Acknowledged Quit command";
printf ("(%s , %d) has left the forum");
sendto(s, reply, strlen(reply), 0, (struct sockaddr *) &from, fromlen);
close(s);
while ('\n' != getchar()){
getchar();
exit(1);
}
}
if (message = strstr(message, ".send")){
//parse .send
//parse username
sendto(s, message, strlen(message), 0, (struct sockaddr *) &from, fromlen);
}
else {
printf("(%s , %d) said : ", inet_ntoa(from.sin_addr), ntohs(from.sin_port));
sendto(s, message, strlen(message), 0, (struct sockaddr *) &from, fromlen);
}
}
}