1. 程式人生 > >C語言socket程式設計---udp通訊及廣播

C語言socket程式設計---udp通訊及廣播

上篇實現了TCP通訊的例子。由於專案中需要一個伺服器向多臺客戶端傳送訊息。

通過udp這種無連線的通訊,將client.c增加一句

/* 設定通訊方式對廣播,即本程式傳送的一個訊息,網路上所有主機均可以收到 */
    yes = 1;
    setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &yes, sizeof(yes));

來設定傳送的訊息為廣播形式。

直接貼程式碼:

client.c

//
//  client.c
//  udp
//
//  Created by lovekun on 14-11-2.
//  Copyright (c) 2014年 care.jiangnan. All rights reserved.
//

/*client.c*/

#include <time.h>
#include <sys/time.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <strings.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h> /* netbd.h is needed for struct hostent =) */

#define PORT 1234 /* Open Port on Remote Host */
#define MAXDATASIZE 100 /* Max number of bytes of data */

/*
 udp廣播通訊,執行時需要兩個引數如下:
 ./client 192.168.1.255
 這樣便會對192.168.1這個網段內所有開著./server的主機發送資料
 */
int main(int argc, char *argv[])
{
    
    int fd, numbytes; /* files descriptors */
    char recvbuf[MAXDATASIZE]; /* buf will store received text */
    char sendbuf[MAXDATASIZE];
    struct hostent *he; /* structure that will get information about remote host */
    struct sockaddr_in server,client; /* server's address information */
    int yes;
    
    /* this is used because our program will need two argument (IP address and a message */
    
    if (argc !=2) {
        printf("Usage: %s <IP Address> \n",argv[0]);
        exit(1);
    }
    
    if ((he=gethostbyname(argv[1]))==NULL){ // calls gethostbyname()
        printf("gethostbyname() error\n");
        exit(1);
    }
    
    
    if ((fd=socket(AF_INET, SOCK_DGRAM, 0))==-1){ // calls socket()
        printf("socket() error\n");
        exit(1);
    }
    
    /* 設定通訊方式對廣播,即本程式傳送的一個訊息,網路上所有主機均可以收到 */
    yes = 1;
    setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &yes, sizeof(yes));
    
    bzero(&server,sizeof(server));
    server.sin_family = AF_INET;
    server.sin_port = htons(PORT); /* htons() is needed again */
    server.sin_addr = *((struct in_addr *)he->h_addr); /*he->h_addr passes "*he"'s info to "h_addr" */
    
    socklen_t len;
    len=sizeof(struct sockaddr_in);
    while (1) {
        printf("input message:");
        fgets(sendbuf,40,stdin);
        sendto(fd,sendbuf,strlen(sendbuf),0,(struct sockaddr *)&server,len);
        if ((numbytes=recvfrom(fd,recvbuf,MAXDATASIZE,0,(struct sockaddr *)&server,&len)) == -1){ /* calls recvfrom() */
            printf("recvfrom() error\n");
            exit(1);
        }
        recvbuf[numbytes]='\0';
        
        
    }
    
    close(fd); /* close fd */
}


server.c

//
//  server.c
//  udp
//
//  Created by lovekun on 14-11-2.
//  Copyright (c) 2014年 care.jiangnan. All rights reserved.
//

/* server.c */

#include <stdio.h> /* These are the usual header files */
#include <string.h>
#include <unistd.h> /* for close() */
#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define PORT 1234 /* Port that will be opened */
#define MAXDATASIZE 100 /* Max number of bytes of data */

main()
{

    
    int sockfd; /* socket descriptors */
    struct sockaddr_in server; /* server's address information */
    struct sockaddr_in client; /* client's address information */
    socklen_t sin_size;
    int num;
    char recvmsg[MAXDATASIZE]; /* buffer for message */
    char sendmsg[MAXDATASIZE];
    char condition[] = "quit";
    /* Creating UDP socket */
    if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
        /* handle exception */
        perror("Creating socket failed.");
        exit(1);
    }
    
    bzero(&server,sizeof(server));
    server.sin_family=AF_INET;
    server.sin_port=htons(PORT);
    server.sin_addr.s_addr = htonl (INADDR_ANY);
    if (bind(sockfd, (struct sockaddr *)&server, sizeof(struct sockaddr)) == -1) {
        /* handle exception */
        perror("Bind error.");
        exit(1);
    }
    
    sin_size=sizeof(struct sockaddr_in);
    while (1) {
        num = recvfrom(sockfd,recvmsg,MAXDATASIZE,0,(struct sockaddr *)&client,&sin_size);
        if (num < 0){
            perror("recvfrom error\n");
            exit(1);
        }
        
        recvmsg[num] = '\0';
        
        printf("You got a message (%s) from %s\n",recvmsg,inet_ntoa(client.sin_addr) ); /* prints client's IP */
        if(strcmp(recvmsg,condition)==0) break;
        
        int i=0;
        for(i = 0 ; i < num ; i ++)
        {
            sendmsg[i] = recvmsg[num-1-i];
        }
        sendmsg[num]='\0';
        
        sendto(sockfd,sendmsg,strlen(sendmsg),0,(struct sockaddr *)&client,sin_size);
        
    }
    
    close(sockfd); /* close listenfd */ 
}