⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chatmb.c

📁 chat program in linux use multiple broadcase implement by c language
💻 C
字号:
#include <sys/utsname.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <error.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>


//#define struct sockaddr ( struct sockaddr )
#define MAXLINE 4096
void recv_all ( int , socklen_t );
void send_all ( int sendfd , struct sockaddr * sadest ,socklen_t salen , const char * name );
int udp_client(const char *host, const char *serv, struct sockaddr **saptr, socklen_t *lenp);
char *sock_ntop(const struct sockaddr *sa, socklen_t salen);

int main ( int argc , char ** argv ) 
{
  int sendfd ;
  int recvfd ;
  socklen_t templen;
  socklen_t salen ;
  const int on = 1 ;
  const int flag = 0 ;
  struct sockaddr *sasend ;
  struct sockaddr *sarecv ;
  struct ip_mreq req;
  struct sockaddr_in tempaddr ;

  if ( argc != 4 ) {
    printf ( "Usage : chat < IP-multicast-address > < port > < name >\n" );
    exit ( 0 );
  }

  printf ( "\nThe program is for chat !\n\n" );

  sendfd = udp_client ( argv [1] , argv [2] , ( struct sockaddr ** )&sasend , &salen );
  recvfd = socket ( sasend -> sa_family , SOCK_DGRAM , 0 );
  setsockopt ( recvfd , SOL_SOCKET , SO_REUSEADDR , & on , sizeof ( on ) );
  sarecv = malloc ( salen ) ;
  memcpy ( sarecv , sasend , salen );
  bind ( recvfd , sarecv ,salen );

  memcpy(&req.imr_multiaddr , & ( ( const struct sockaddr_in * )sasend ) -> sin_addr , sizeof ( struct in_addr ) );
  req.imr_interface.s_addr = htonl ( INADDR_ANY );
  setsockopt ( recvfd , IPPROTO_IP , IP_ADD_MEMBERSHIP , &req , sizeof ( req ) );
  setsockopt ( recvfd , IPPROTO_IP , IP_MULTICAST_LOOP , &flag , sizeof ( flag ) );

  if ( fork ( ) == 0 ) 
    recv_all ( recvfd , salen  );
  send_all ( sendfd , sasend , salen ,argv[3] ) ;
}

void send_all ( int sendfd , struct sockaddr * sadest ,socklen_t salen ,const char * name ) 
{
  static char line[MAXLINE];
  static char chat[MAXLINE + 1];
  static char say [ ] = "say :";
  struct utsname myname;
  int n;

  if ( uname ( &myname ) < 0 ) {
    perror ( "uname error" ) ;
    exit ( 1 ) ;
  }

  snprintf( line ,sizeof ( line ) , "%s, %d\n%s %s " , myname.nodename , getpid () , name , say );
  n = strlen ( line ) ;
  while ( fgets ( chat , MAXLINE , stdin ) != NULL ){
    strcat( line , chat );
    sendto ( sendfd , line , strlen ( line ) , 0 , sadest , salen ) ;
    strncpy( line , line , n );
    line [n] = '\0';
  }
}

void recv_all ( int recvfd , socklen_t salen ) 
{
  int n ;
  char line[MAXLINE + 1] ;
  socklen_t len ;
  struct sockaddr * safrom ;
  safrom = malloc ( salen ) ;
  for ( ; ; ) {
    len = salen ;
    n = recvfrom ( recvfd , line , MAXLINE , 0 , safrom , & len ) ;
    line [ n ] = 0 ;
    printf ( "\n\033[01;34mfrom %s : %s" , sock_ntop ( safrom ,len ) , line ) ;
    printf ( "\033[0m\n" );

  }
}

int udp_client(const char *host, const char *serv, struct sockaddr **saptr, socklen_t *lenp)
{
	int				sockfd, n;
	struct addrinfo	hints, *res, *ressave;

	bzero(&hints, sizeof(struct addrinfo));
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_DGRAM;

	if ( (n = getaddrinfo(host, serv, &hints, &res)) != 0){
		printf ("udp_client error for %s, %s: %s",
				 host, serv, gai_strerror(n));
		exit ( 1 ) ;
	}
	ressave = res;

	do {
		sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
		if (sockfd >= 0)
			break;		/* success */
	} while ( (res = res->ai_next) != NULL);


	if (res == NULL)	/* errno set from final socket() */
		printf("udp_client error for %s, %s", host, serv);

	*saptr = malloc(res->ai_addrlen);
	memcpy(*saptr, res->ai_addr, res->ai_addrlen);
	*lenp = res->ai_addrlen;

	freeaddrinfo(ressave);

	return(sockfd);
}

char *sock_ntop(const struct sockaddr *sa, socklen_t salen)
{
    char portstr[8];
    static char str[128];		/* Unix domain is largest */

	switch (sa->sa_family) {
	case AF_INET: {
		struct sockaddr_in	*sin = (struct sockaddr_in *) sa;

		if (inet_ntop(AF_INET, &sin->sin_addr, str, sizeof(str)) == NULL)
			return(NULL);
		if (ntohs(sin->sin_port) != 0) {
			snprintf(portstr, sizeof(portstr), ":%d", ntohs(sin->sin_port));
			strcat(str, portstr);
		}
		return(str);
	}
	}
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -