天天看点

Linux 网络编程——TCP&UDP范例Linux 网络编程——TCP&UDP范例

Linux 网络编程——TCP&UDP范例

TCP基础变成范例

程序功能:服务端启动并接收客户端的连接,客户端连接后,服务端向客户端发送当前时间并显示在客户端上,服务端显示当前连接的客户端的IP地址和port。

服务端代码time_tcp_server.c

#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <signal.h>
#include <time.h>

int sockfd;

void sig_handler(int signo)
{
    if(signo == SIGINT){
        printf("server close\n");
        /* 步骤6:关闭socket*/
        close(sockfd);
        exit();
    }
}
/*输出链接上来的客户端信息*/
void out_addr(struct sockaddr_in *clientaddr)
{
    //将端口从网络字节序转换成主机字节序
    int port = ntohs(clientaddr->sin_port);
    char ip[];
    memset(ip, , sizeof(ip));
    //将IP地址从网络字节序转换成点分十进制
    inet_ntop(AF_INET, &clientaddr->sin_addr.s_addr,
            ip, sizeof(ip));
    printf("client: %s(%d) connected\n",ip,port);
}
void do_service(int fd)
{
    //获得系统时间
    long t = time();
    char *s = ctime(&t);
    size_t size = strlen(s) * sizeof(char);
    //将服务器获得的系统时间写会客户端
    if(write(fd,s,size) != size){
        perror("write error\n");
    }
}
int main(int argc,char *argv[])
{
    if(argc < ){
        printf("usage:%s #port\n",argv[]);
        exit();
    }
    if(signal(SIGINT,sig_handler) == SIG_ERR){
        perror("signal sigint error\n");
        exit();
    }
    /* 步骤1:创建socket(套接字)
     * 注:socket创建在内核中,是一个结构体
     * AF_INET:IPV4
     * SOCK_STREAM:TCP协议
     * */
    sockfd = socket(AF_INET,SOCK_STREAM,);
    /* 步骤2:调用bind函数将socket和地址
     *  (包括ip、port)进行绑定
     * */
    struct sockaddr_in serveraddr;
    memset(&serveraddr,,sizeof(serveraddr));
    serveraddr.sin_family = AF_INET;    //IPV4
    serveraddr.sin_port = htons(atoi(argv[])); //port
    serveraddr.sin_addr.s_addr = INADDR_ANY;
    if(bind(sockfd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)) < ){
        perror("bind error\n");
        exit();
    }   
    /* 步骤3:调用listen函数启动监听(制定port监听)
     *    通知系统去接受来自客户端的链接请求
     *    (将接受到的客户端对应请求放置到对应的队列中)
     * 第二个参数:指定队列的长度
     * */
    if(listen(sockfd, ) < ){
        perror("listen error\n");
        exit();
    }
    /* 步骤4:调用accept函数从队列中获得一个客户端的请求连接,
     *    并返回新的socket描述符
     * 注意:若没有客户端连接,调用此函数后会阻塞,
     *   直到获得一个客户端的链接
     * */
    struct sockaddr_in clientaddr;
    socklen_t clientaddr_len = sizeof(clientaddr);
    while(){
        int fd = accept(sockfd,(struct sockaddr*)&clientaddr,
                &clientaddr_len);
        if(fd < ){
            perror("accept error\n");
            continue; 
        }
        /* 步骤5:调用IO函数(read/write)和链接的客户端进行
         *    双向的通信
         * */
        out_addr(&clientaddr);
        do_service(fd);
        /* 步骤6:关闭socket*/
        close(fd);
    }
    return ;
}
           

客户端代码time_tcp_client.c

#include <netdb.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <memory.h>
#include <arpa/inet.h>
#include <unistd.h>

int main(int argc,char *argv[])
{
    if(argc < ){
        printf("usage:%s ip port\n",argv[]);
        exit();
    }
    /* 步骤1:创建socket*/
    int sockfd = socket(AF_INET, SOCK_STREAM, );
    if(sockfd < ){
        perror("socket error\n");
        exit();
    }
    //往serveraddr中填入ip,port和地址族类型(ipv4)
    struct sockaddr_in serveraddr;
    memset(&serveraddr, , sizeof(serveraddr));
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_port = htons(atoi(argv[]));
    //将ip地址转换成网络字节序
    inet_pton(AF_INET, argv[], &serveraddr.sin_addr.s_addr);
    /* 步骤2:客户端调用connect函数连接到服务器端*/
    if(connect(sockfd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)) < ){
        perror("connect error\n");
        exit();
    }
    /* 步骤3:调用IO函数(read/write)和服务端进行双向通信*/
    char buffer[];
    memset(buffer, , sizeof(buffer));
    size_t size;
    if((size = read(sockfd, buffer, sizeof(buffer))) < ){
        perror("read error\n");
        exit();
    }
    if(write(STDOUT_FILENO, buffer, size) != size){
        perror("write error\n");
        exit();
    }
    /* 步骤4:关闭socket*/
    close(sockfd);

    return ;
}
           

UDP基础变成范例

程序功能:服务端启动并接收客户端的连接,客户端连接后,服务端向客户端发送当前时间并显示在客户端上,服务端显示当前连接的客户端的IP地址和port。

服务端代码time_udp_server.c

#include <stdio.h>
#include <netdb.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <time.h>

int sockfd;

void sig_handler(int signo)
{
    if(signo == SIGINT){
        printf("server close\n");
        close(sockfd);
        exit();
    }
}

//输出客户端信息
void out_addr(struct sockaddr_in *clientaddr)
{
    char ip[];
    memset(ip, , sizeof(ip));
    inet_ntop(AF_INET, &clientaddr->sin_addr.s_addr, ip, sizeof(ip));
    int port = ntohs(clientaddr->sin_port);
    printf("client: %s(%d)\n", ip, port);
}

//和客户端进行通信
void do_service()
{
    struct sockaddr_in clientaddr;
    socklen_t len = sizeof(clientaddr);
    char buffer[];
    memset(buffer, , sizeof(buffer));
    //接收客户端数据报文
    if(recvfrom(sockfd, buffer, sizeof(buffer), ,
            (struct sockaddr*)&clientaddr, &len) < ){
        perror("recvfrom error");
    }else{
        out_addr(&clientaddr);
        printf("client send into: %s\n", buffer);

        //向客户端发送数据报文
        long int t = time();
        char *ptr = ctime(&t);
        size_t size = strlen(ptr) * sizeof(char);
        if(sendto(sockfd, ptr, size, ,
                (struct sockaddr*)&clientaddr, len) < ){
            perror("send error");
        }
    }
}

int main(int argc, char *argv[])
{
    if(argc < ){
        printf("usage: %s port\n", argv[]);
        exit();
    }
    if(signal(SIGINT, sig_handler) == SIG_ERR){
        perror("signal sifint error");
        exit();
    }
    /* 步骤1:创建socket*/
    sockfd = socket(AF_INET, SOCK_DGRAM, );
    if(sockfd < ){
        perror("socket error");
        exit();
    }
    int ret;
    int opt = ;
    //设置套接字选项
    if((ret = setsockopt(sockfd, SOL_SOCKET, 
            SO_REUSEADDR, &opt, sizeof(opt))) < ){
        perror("setsockopt error");
        exit();
    }
    /* 步骤2:调用bind函数对socket和地址进行绑定*/
    struct sockaddr_in serveraddr;
    memset(&serveraddr, , sizeof(serveraddr));
    serveraddr.sin_family = AF_INET;        //ipv4
    serveraddr.sin_port = htons(atoi(argv[])); //port
    serveraddr.sin_addr.s_addr = INADDR_ANY;    //ip
    if(bind(sockfd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)) < ){
        perror("bind error");
        exit();
    }
    /* 步骤3:和客户端进行双向的通信*/
    while(){
        do_service();
    }
    return ;
}
           

客户端代码time_udp_client.c

#include <stdio.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netdb.h>
#include <unistd.h>
#include <string.h>
#include <memory.h>

int sockfd;

int main(int argc, char *argv[])
{
    if(argc < ){
        printf("usage: %s ip,port,msg", argv[]);
        exit();
    }
    /* 步骤1:创建socket*/
    if((sockfd = socket(AF_INET, SOCK_DGRAM,)) < ){
        perror("socket error");
        exit();
    }
    struct sockaddr_in serveraddr;
    memset(&serveraddr, , sizeof(serveraddr));
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_port = htons(atoi(argv[]));
    inet_pton(AF_INET, argv[], &serveraddr.sin_addr.s_addr);

    char buffer[];
    memset(buffer, , sizeof(buffer));
    strcpy(buffer,argv[]);
    if(sendto(sockfd, buffer, sizeof(buffer), , (struct        sockaddr*)&serveraddr, sizeof(serveraddr)) < ){
        perror("send error");
        exit();
    }else{
        memset(buffer, , sizeof(buffer));
        if(recv(sockfd, buffer, sizeof(buffer), ) < ){
            perror("recv error");
            exit();
        }else{
            printf("%s", buffer);
        }
    }
    close(sockfd);
    return ;
}
           

继续阅读