linux网络编程之udp模板

TCP中,客户端调用connect函数会向服务器端触发一个TCP3次握手过程,去建立一条TCP连接;而在UDP中,客户端调用该函数主要的作用是告诉后面将要调用的recvfrom函数,仅仅只接受在connect函数中指明的服务器发来的数据,这样当后面调用recvfrom时最后两个参数就可以置为NULL了。也就说对UDP编程来说,客户端调用connect是可选的:如果调用了connect函数,recvfrom就可以省掉最后两个参数;如果不调用connectrecvfrom必须指明从哪儿收数据。


/* server */

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

#define BUFSIZE 1024

int main(int argc, char *argv[])
{
    int sockfd = -1;
    int clientlen = 0;
    int ret;
    struct sockaddr_in serveraddr, clientaddr;
    char buf[BUFSIZE];
    char sndbuf[BUFSIZE];

    if (2 != argc || 0 > argv[1]){
        printf("usage: %s:portnumber\n", argv[0]);
        exit(1);
    }

    if ( -1 == (sockfd = socket(AF_INET, SOCK_DGRAM, 0))){
        perror("socket error:");
        exit(1);
    }

    bzero(&serveraddr, sizeof(serveraddr));
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_port = htons(atoi(argv[1]));
    serveraddr.sin_addr.s_addr = INADDR_ANY; //由于该值为0,所以转不转字节序都一样

    if (-1 == (bind(sockfd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)))){
        perror("bind error:");
        exit(1);
    }

    clientlen = sizeof(clientaddr);

    while (1){
        ret = recvfrom(sockfd, buf, sizeof(buf), 0, &clientaddr, &clientlen);
        if (ret < 0){
            printf("recv data from %s:%d error\n", inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port));
        }else if (ret == 0){
            perror("client has been closed socket");
        }else{
            printf("From %s:%d,%s\n", inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port), buf);
            memset(sndbuf, 0, sizeof(sndbuf));

            switch(buf[0]){
                case 'a':
                    strcpy(sndbuf, "After u, lady...");
                    break;
                case 'b':
                    strcpy(sndbuf, "Before u, sir...");
                    break;
                case 'c':
                    strcpy(sndbuf, "can u?");
                    break;
                default:
                    strcpy(sndbuf, "I don't know what u want");
            }
            puts(sndbuf);

            sendto(sockfd, sndbuf, strlen(sndbuf), 0, (struct sockaddr *)&clientaddr, sizeof(clientaddr));
        }

        memset(buf, 0, sizeof(buf));
    }


    return 0;
}

/* client */

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


int main(int argc, char *argv[])
{
    int portnumber = 0;
    int sockfd = -1;
    struct hostent *host;
    struct sockaddr_in serveraddr;
    char buf[1024] = {0};
    char sndbuf[1024] = {0};
    int len, ret;

    if (3 != argc || 0 > (portnumber = atoi(argv[2]))){
        printf("usage:%s hostname portnumber\n", argv[0]);
        exit(1);
    }

    if (NULL == (host = gethostbyname(argv[1]))){
        perror("gethostname error:");
        exit(1);
    }

    if (-1 == (sockfd = socket(AF_INET, SOCK_DGRAM, 0))){
        perror("socket error:");
        exit(1);
    }

    bzero(&serveraddr, sizeof(serveraddr));
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_port = htons(portnumber);
    serveraddr.sin_addr = *(struct in_addr *)host->h_addr;

    if (-1 == connect(sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr))){
        perror("connect error:");
        exit(1);
    }

    while (1){
        memset(sndbuf, 0, sizeof(sndbuf));
        len = read(0, sndbuf, sizeof(sndbuf));
        ret = sendto(sockfd, sndbuf, strlen(sndbuf), 0, NULL, NULL);
        printf("len is %d, ret is %d\n", len, ret);
        if (ret == len){
            memset(buf, 0, sizeof(buf));
            ret = recvfrom(sockfd, buf, sizeof(buf), 0, NULL, NULL);
            if (ret < 0){
                perror("read from server error");
            }else if (ret == 0){
                perror("server has been closed");
            }else{
                buf[ret] = 0;
                printf("from server:%s\n", buf);
            }
        }
    }

    return 0;
}

原文:http://blog.chinaunix.net/uid-23069658-id-3276167.html



你可能感兴趣的:(linux网络编程之udp模板)