How to make a chat between two clients?

I have some C code of a server and a client, the client sends a message to server and receive back "Hello" + message. The server can treat more clients using select function. I want to modify this code to obtain a chat between two clients.
I have tried on client to make a fork, the child to receive new messages and the father to input messages but it doesn't seem to work, how can I sync the clients that when one sends a message the other one to be ready to receive?
This is the original code without modifications:
Server
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <string.h>

#define PORT 2728

extern int errno;

char * conv_addr (struct sockaddr_in address)
{
  static char str[25];
  char port[7];

  strcpy (str, inet_ntoa (address.sin_addr));	

  bzero (port, 7);
  sprintf (port, ":%d", ntohs (address.sin_port));	
  strcat (str, port);
  return (str);
}

int sayHello(int fd)
{
  char buffer[100];		
  int bytes;			
  char msg[100];		
  char msgrasp[100]=" ";

  bytes = read (fd, msg, sizeof (buffer));
  if (bytes < 0)
    {
      perror ("read() error from client.\n");
      return 0;
    }
  printf ("[server] I've received the message...%s\n", msg);
        
  bzero(msgrasp,100);
  strcat(msgrasp,"Hello ");
  strcat(msgrasp,msg);
      
  printf("[server] Send back the message...%s\n",msgrasp);
      
  if (bytes && write (fd, msgrasp, bytes) < 0)
    {
      perror ("[server] write() error.\n");
      return 0;
    }
  
  return bytes;
}

int main ()
{
  struct sockaddr_in server;
  struct sockaddr_in from;
  fd_set readfds;	
  fd_set actfds;	
  struct timeval tv;	
  int sd, client;		
  int optval=1; 	
  int fd;	
  int nfds;		
  int len;	

  if ((sd = socket (AF_INET, SOCK_STREAM, 0)) == -1)
    {
      perror ("[server] socket() Error.\n");
      return errno;
    }

  setsockopt(sd, SOL_SOCKET, SO_REUSEADDR,&optval,sizeof(optval));

  bzero (&server, sizeof (server));

  server.sin_family = AF_INET;
  server.sin_addr.s_addr = htonl (INADDR_ANY);
  server.sin_port = htons (PORT);

  if (bind (sd, (struct sockaddr *) &server, sizeof (struct sockaddr)) == -1)
    {
      perror ("[server] bind() Error.\n");
      return errno;
    }

  if (listen (sd, 5) == -1)
    {
      perror ("[server] listen() Error.\n");
      return errno;
    }
  
  FD_ZERO (&actfds);
  FD_SET (sd, &actfds);

  tv.tv_sec = 1;	
  tv.tv_usec = 0;
  
  nfds = sd;

  printf ("[server] Wait at port %d...\n", PORT);
  fflush (stdout);
        
  while (1)
    {
      bcopy ((char *) &actfds, (char *) &readfds, sizeof (readfds));

      if (select (nfds+1, &readfds, NULL, NULL, &tv) < 0)
	{
	  perror ("[server] select() Error.\n");
	  return errno;
	}
      if (FD_ISSET (sd, &readfds))
	{
	  len = sizeof (from);
	  bzero (&from, sizeof (from));
	  
	  client = accept (sd, (struct sockaddr *) &from, &len);

	  if (client < 0)
	    {
	      perror ("[server] accept() Error.\n");
	      continue;
	    }

          if (nfds < client)
            nfds = client;
            	 
	  FD_SET (client, &actfds);

	  printf("[server] Client with descriptor %d is connected from address %s.\n",client, conv_addr (from));
	  fflush (stdout);
	}    
      for (fd = 0; fd <= nfds; fd++)	
	{	 
	  if (fd != sd && FD_ISSET (fd, &readfds))
	    {	
	      if (sayHello(fd))
		{
		  printf ("[server] Client with descriptor %d has disconnected.\n",fd);
		  fflush (stdout);
		  close (fd);
		  FD_CLR (fd, &actfds);
		  
		}
	    }
	}			/* for */
    }				/* while */
}				/* main */


Client
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <netdb.h>
#include <string.h>

extern int errno;

int port;

int main (int argc, char *argv[])
{
  int sd;			
  struct sockaddr_in server;
  char msg[100];		

  if (argc != 3)
    {
      printf ("[client] Sintax: %s <address_server> <port>\n", argv[0]);
      return -1;
    }

  port = atoi (argv[2]);

  if ((sd = socket (AF_INET, SOCK_STREAM, 0)) == -1)
    {
      perror ("[client] socket() error.\n");
      return errno;
    }
  
  server.sin_family = AF_INET;
  server.sin_addr.s_addr = inet_addr(argv[1]);
  server.sin_port = htons (port);
    
  if (connect (sd, (struct sockaddr *) &server,sizeof (struct sockaddr)) == -1)
    {
      perror ("[client]connect() error.\n");
      return errno;
    }

  bzero (msg, 100);
  printf ("[client]Type a name: ");
  fflush (stdout);
  read (0, msg, 100);
    
  if (write (sd, msg, 100) <= 0)
    {
      perror ("[client]write() error to server.\n");
      return errno;
    }

  if (read (sd, msg, 100) < 0)
    {
      perror ("[client]read() error from server.\n");
      return errno;
    }

  printf ("[client]Received message is: %s\n", msg);

  close (sd);
}

Topic archived. No new replies allowed.