/* inet.h:   for Interactiv Unix V.3  */

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

#define SERV_TCP_PORT 6002
#define SERV_UDP_PORT 6003
#define SERV_HOST_ADDR "141.20.20.18"

#define MAXLINE 512
/* s_sock.c  - Server for tcp-socket */
/*next*/
#include "inet.h"

talk(sockfd)
int sockfd;
{ 
   int n;
   char sendline[MAXLINE];

   while((n=read(sockfd,sendline,MAXLINE)) > 0) {
      write(1,sendline,n);
      write(1,"s> ",3);
      if ((n=read(0,sendline,MAXLINE)) <= 0) break;
      if (write(sockfd,sendline,n) !=n) break;
   }
}
main(argc,argv)
int argc;
char *argv[];
/*next*/
{
   int sockfd, newsockfd, clilen, childpid;
   struct sockaddr_in  cli_addr, serv_addr;
        int i;

   if (( sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
      fprintf(stderr,"server: can't open stream socket\n");
      exit(-1);
        }
   bzero((char *) &serv_addr, sizeof(serv_addr));
   serv_addr.sin_family = AF_INET;
   serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
   serv_addr.sin_port = htons(SERV_TCP_PORT);
   if ((i=bind(sockfd, (struct sockaddr *) &serv_addr,
                                    sizeof(serv_addr))) < 0){
      fprintf(stderr,
                   "server: can't bind local address: %d\n",i);
      exit(-2);
   }
/*next*/
   listen(sockfd,5);
   for (;;) {
      clilen = sizeof(cli_addr);
      newsockfd = 
         accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
      if  (newsockfd < 0){
         fprintf(stderr,"server: accept error\n");
         exit(-3);
      }
      if ((childpid = fork()) < 0) {
         fprintf(stderr,"server: fork error\n");
         exit(-4);
      }
      else if (childpid == 0) {
              close(sockfd); talk(newsockfd);
              exit(0);
           }
      close(newsockfd);
   }
}
/*next*/
/* c_sock.c - client for tcp-socket */
#include "inet.h"
/* read from 0, write to socket, read from socket, write to 1 */

talk(sockfd)
register int sockfd;
{
   int n;
   char sendline[MAXLINE];

   while (write(1,"c: ",3),(n = read(0,sendline, MAXLINE)) > 0) {
      if (write(sockfd, sendline, n) != n) break;
      if ((n=read(sockfd,sendline,MAXLINE)) <= 0) break;
      write(1,sendline,n);
   }
}

main(argc,argv)
int argc;
char *argv[];
/*next*/
{  int sockfd;
   struct sockaddr_in serv_addr;

   bzero((char *) &serv_addr, sizeof(serv_addr));
   serv_addr.sin_family = AF_INET;
   serv_addr.sin_port = htons(SERV_TCP_PORT);
   serv_addr.sin_addr.s_addr = 
                          inet_addr(SERV_HOST_ADDR);
   if ((sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0) {
      fprintf(stderr,"c_sock: can't open stream socket\n");
      exit(-1);
   }
   if (connect(sockfd, (struct sockaddr *) &serv_addr,
            sizeof(serv_addr)) < 0)  {
      fprintf(stderr,"c_sock: can't connect to server\n");
      exit(-2);
   }
   talk(sockfd);
   exit(0);
}
/*next*/
/* su_sock.c  - Server for udp-socket */

#include "inet.h"

talk(sockfd,pcli_addr,maxln)
int sockfd;
struct sockaddr *pcli_addr;
int maxln;
{ 
    int n, clilen = maxln;
    char sendline[MAXLINE];
    while((n=recvfrom(sockfd,sendline,MAXLINE,0,
                              pcli_addr,&clilen)) > 0) {
        write(1,sendline,n);
        write(1,"s> ",3);
        if ((n=read(0,sendline,MAXLINE)) <= 0) break;
        if (sendto(sockfd,sendline,n,0,pcli_addr,clilen) !=n)
              break;
    }
}
/*next*/
main(argc,argv)
int argc;
char *argv[];
{   int sockfd;
    struct sockaddr_in  cli_addr, serv_addr;
    if (( sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
        fprintf(stderr, "su_sock: can't open datagram socket\n");
        exit(-1);
    }
    bzero((char *) &serv_addr, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    serv_addr.sin_port = htons(SERV_UDP_PORT);
    if (bind(sockfd, (struct sockaddr *) &serv_addr,
             sizeof(serv_addr)) < 0){
        fprintf(stderr,"su_sock: can't bind local address\n");
        exit(-2);
    }
    talk(sockfd,(struct sockaddr *) &cli_addr,sizeof(cli_addr));
}
/*next*/
/* cu_sock.c - client for udp-socket */
#include "inet.h"
/* read from 0, write to socket, read from socket, write to 1 */
talk(sockfd,pserv_addr,servlen)
register int sockfd;
struct sockaddr *pserv_addr;
int servlen;
{
  int n;
  char sendline[MAXLINE];
  while (write(1,"c> ",3),(n = read(0,sendline, MAXLINE)) > 0) {
    if (sendto(sockfd, sendline, n,0,pserv_addr,servlen) != n) break;
    if ((n=recvfrom(sockfd,sendline,MAXLINE,0,(struct sockaddr *) 0,
                            (int *) 0)) <= 0) break;
    write(1,sendline,n);
  }
}
main(argc,argv)
int argc;
char *argv[];
/*next*/
{  int sockfd;
   struct sockaddr_in serv_addr, cli_addr;
   bzero((char *) &serv_addr, sizeof(serv_addr));
   serv_addr.sin_family = AF_INET;
   serv_addr.sin_port = htons(SERV_UDP_PORT);
   serv_addr.sin_addr.s_addr = inet_addr(SERV_HOST_ADDR);
   if ((sockfd = socket(AF_INET,SOCK_DGRAM,0)) < 0) {
      fprintf(stderr,"cu_sock: can't open stream socket\n");
      exit(-1);                                     }
   bzero((char *) &cli_addr, sizeof(cli_addr));
   cli_addr.sin_family = AF_INET;
   cli_addr.sin_addr.s_addr = htonl(INADDR_ANY);
   cli_addr.sin_port = htons(0);
   if (bind(sockfd,(struct sockaddr *) &cli_addr,
                                  sizeof(cli_addr)) < 0){
         fprintf(stderr,"cu_sock: can't bind port\n");
         exit(-2);                                      }
   talk(sockfd,(struct sockaddr *) &serv_addr, sizeof(serv_addr));
   exit(0);
}
