Reputation: 1
I'm trying to create a chat program using UDP. I've created a parent and a child process in both the client and the server to separately receive and send messages. Problem is the server can't send. Help please. Here's my code.
CLIENT
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
#include <sys/stat.h>
#include <arpa/inet.h>
int main(int argc, char **argv)
{
int sockfd;
struct sockaddr_in servaddr;
socklen_t len = sizeof(servaddr);
char mesg[1024], rmesg[1024];
pid_t pid;
if(argc!=2){
printf("Usage: %s <ip_addr>\n",argv[0]);
exit(1);
}
sockfd = socket(PF_INET,SOCK_DGRAM,0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(54321);
inet_pton(AF_INET,argv[1],&servaddr.sin_addr);
pid = fork();
if(pid == 0) {
printf("Type 'exit' to Exit. \n");
while(1){
fgets(mesg,sizeof(mesg),stdin);
sendto(sockfd,mesg,strlen(mesg),0,(const struct sockaddr *)&servaddr,len);
if(strcmp(mesg, "exit\n") == 0)
break;
}
close(sockfd);
kill(pid, SIGINT);
exit(0);
}else{
while(1){
memset(rmesg,0,sizeof(rmesg));
if(recv(sockfd,rmesg,sizeof(rmesg),0) > 0 ){
printf("From Server: %s", rmesg);
}
}
}
close(sockfd);
return 0;
}
SERVER
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
#include <sys/stat.h>
#include <arpa/inet.h>
int main(int argc, char **argv)
{
int sockfd1;
struct sockaddr_in servaddr,cliaddr;
socklen_t len = sizeof(cliaddr);
char cli_ip[32];
char mesg[1024], smesg[1024];
pid_t pid1;
sockfd1 = socket(PF_INET,SOCK_DGRAM,0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(54321);
inet_ntop(AF_INET,(struct in_addr *) &cliaddr.sin_addr, cli_ip, sizeof(cli_ip) );
if ( bind( sockfd1, (struct sockaddr*) &servaddr, sizeof(servaddr) ) < 0 ){
perror(NULL);
exit(-1);
}
pid1 = fork();
if(pid1 == 0){
while(1){
memset(mesg,0,sizeof(mesg));
if( recvfrom(sockfd1,mesg,sizeof(mesg),0,(struct sockaddr *)&cliaddr,&len) > 0 ){
printf("From client: %s",mesg);
}
}
}else{
printf("Type 'exit' to Exit. \n");
while(1){
fgets(smesg,sizeof(smesg),stdin);
sendto(sockfd1,smesg,strlen(smesg),0,(struct sockaddr *)&cliaddr,len);
if(strcmp(smesg, "exit\n") == 0)
break;
}
close(sockfd1);
kill(pid1, SIGINT);
exit(0);
}
return 0;
}
Upvotes: 0
Views: 315
Reputation: 4666
WHy are you using hte same socket for both server and client? This does not make sense. A simpler alternative would be to use two threads. One thread handling the server socket and the other thread handling the client thread. And ofcourse, you would need to have two sockets as well -- one for the server and one for the client. Also, the sendto() needs to have the address and port information of the receiver.
Upvotes: 0
Reputation: 182609
The problem is most likely in the client:
while(1){ if(recv(sockfd,rmesg,sizeof(rmesg),0) > 0 ){ printf("From Server: %s", rmesg); } }
You are calling recv
on an unconnected socket. You're likely getting an error (probably ENOTCONN
) which you are ignoring. And I believe you're also seeing high CPU usage on the clients, since it is continuously looping, failing each system call.
The solution is to use recvfrom
instead. Alternatively you can call connect
on the socket, even if it is SOCK_DGRAM
, but this is not normally done.
Upvotes: 1