If you want an asynchronous chat, you need to have a look at the select or poll functions. From the looks of your code though, I think you will have a hard time integrating either function.
I fixed your code up a bit.
CLIENT:
Code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main(int argc, char *argv[])
{
struct sockaddr_in server_info;
struct hostent *he;
int socket_fd, num, portno, yes = 1;
char buffer[1024];
if (argc != 3) {
printf("USAGE: %s + hostname + port\n", argv[0]);
exit(1);
}
if ((he = gethostbyname(argv[1]))==NULL) {
fprintf(stderr, "Cannot get host name\n");
exit(1);
}
if ((socket_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
fprintf(stderr, "Socket Failure!!\n");
exit(1);
}
setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));
memset(&server_info, 0, sizeof(server_info));
portno = atoi(argv[2]);
server_info.sin_family = AF_INET;
server_info.sin_port = htons(portno);
memcpy(&server_info.sin_addr.s_addr, he->h_addr, he->h_length);
//or you could use -> server_info.sin_addr.s_addr = htonl(INADDR_ANY);
if (connect(socket_fd, (struct sockaddr *)&server_info, sizeof(server_info)) < 0) {
fprintf(stderr, "Connection Failure\n");
exit(1);
}
while(1) {
memset(buffer, 0, sizeof(buffer));
printf("Message: ");
fgets(buffer, sizeof(buffer), stdin);
if ((send(socket_fd, buffer, strlen(buffer), 0)) < 0) {
fprintf(stderr, "Failure Sending Message\n");
close(socket_fd);
exit(1);
}
num = recv(socket_fd, buffer, sizeof(buffer), 0);
if (num == -1) {
fprintf(stderr, "Failure Sending Message\n");
close(socket_fd);
exit(1);
}
else if (num == 0) {
printf("Connection closed\n");
return 0;
}
printf("Server: %s\n",buffer);
}
close(socket_fd);
}
SERVER:
Code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
int main(int argc, char *argv[])
{
if(argc < 3) {
printf("USAGE: %s + hostaddr + port.\n", argv[0]);
exit(1);
}
struct sockaddr_in server;
struct sockaddr_in dest;
struct hostent *he;
int socket_fd, client_fd, num, portno, yes = 1;
socklen_t size;
char buffer[1024];
if ((socket_fd = socket(AF_INET, SOCK_STREAM, 0))== -1) {
fprintf(stderr, "Socket failure!!\n");
exit(1);
}
if(socket_fd) {
do {
{
printf("waiting for a connection.\n");
}
} while(!accept);
}
setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));
he = gethostbyname(argv[1]);
if(he == NULL) {
//This error handling requires errno.h
printf("GETHOSTBYNAME(NULL) error --> %s.\n", strerror(errno));
exit(1);
}
memset(&server, 0, sizeof(server));
memset(&dest,0,sizeof(dest));
portno = atoi(argv[2]);
server.sin_family = AF_INET;
server.sin_port = htons(portno);
memcpy(&server.sin_addr.s_addr, he->h_addr, he->h_length);
if ((bind(socket_fd, (struct sockaddr *)&server, sizeof(server)))== -1) {
fprintf(stderr, "Binding Failure\n");
close(socket_fd);
exit(1);
}
if ((listen(socket_fd, 10))== -1){
fprintf(stderr, "Listening Failure\n");
exit(1);
}
size = sizeof(dest);
if ((client_fd = accept(socket_fd, (struct sockaddr *)&dest, &size))==-1) {
//fprintf(stderr,"Accept Failure\n");
perror("accept");
exit(1);
}
printf("Server got connection from client %s\n", inet_ntoa(dest.sin_addr));
while(1) {
memset(buffer, '\0', sizeof(buffer));
if ((num = recv(client_fd, buffer, sizeof(buffer), 0)) < 0) {
perror("recv");
exit(1);
}
else if (num == 0) {
printf("Connection closed\n");
return 0;
}
printf("Client: %s\n", buffer);
printf("Message: ");
fgets(buffer, sizeof(buffer), stdin);
if (send(client_fd, buffer, strlen(buffer), 0) < 0) {
fprintf(stderr,"Failure sending message\n");
close(client_fd);
exit(1);
}
}
close(client_fd);
close(socket_fd);
return 0;
}