linux:套接字编程 UDP

套接字编程

在TCP/IP协议中,IP地址+端口号—->唯一的标识一个进程
IP地址+端口号就是套接字,套接字编程就是两个进程分别有自己的socket,这两个进程的socket组成一对,就唯一的标识了这两个进程之间的连接,然后就可以进行相互的通信了

1.实现一个客户端给服务器发送消息,服务器的作用就是回显客户端发给自己的消息

server.c (服务器端)

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<sys/types.h>
#include<sys/socket.h>
typedef struct sockaddr sockaddr;
typedef struct sockaddr_in sockaddr_in;

#define ERR_EXIT(m)\
    do\
{\
    perror(m);\
    exit(EXIT_FAILURE);\
}while(0)

void Usage(){
    printf("Usage ./server [ip] [port]\n");
    return;
}
int main(int argc,char*argv[]){
    if(3!=argc){
        Usage();
        return 1;
    }
    sockaddr_in local;
    local.sin_family=AF_INET;
    local.sin_addr.s_addr=inet_addr(argv[1]);
    local.sin_port=htons(atoi(argv[2]));
    //1.创建套接字
    int sockfd= socket(AF_INET,SOCK_DGRAM,0);
    if(sockfd<0)
        ERR_EXIT("socket");
    //2.进行绑定
    int ret= bind(sockfd,(sockaddr*)&local,sizeof(local));
    if(ret<0)
        ERR_EXIT("bind"); 
    //3.循环的把客户端发送的数据,给客户端发送回去
    char buf[1024]={0};
    sockaddr_in client;
    while(1){
        socklen_t len=sizeof(client);
        ssize_t s=recvfrom(sockfd,buf,sizeof(buf)-1,0,\
                (sockaddr*)&client,&len);
        if(s>0) {
            buf[s]=0;
            printf("client [%s: %d] say:> %s\n",inet_ntoa(client.sin_addr),\
                    ntohs(client.sin_port),buf);
            sendto(sockfd,buf,strlen(buf),0,\
                    (sockaddr*)&client,sizeof(client));
        }
    }
    return 0;
}

client.c(客户机端)

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<netinet/in.h>
typedef struct sockaddr sockaddr;
typedef struct sockaddr_in sockaddr_in;

#define ERR_EXIT(m)\
    do\
{\
    perror(m);\
    exit(EXIT_FAILURE);\
}while(0)

void Usage(){
    printf("Usage ./client [ip] [port]\n");
    return;
}
int main(int argc,char* argv[]){
    if(3!=argc){
        Usage();
        return 1;
    }
    sockaddr_in server;
    server.sin_family=AF_INET;
    server.sin_addr.s_addr=inet_addr(argv[1]);
    server.sin_port=htons(atoi(argv[2]));
    //1.创建套接字
    int sockfd=socket(AF_INET,SOCK_DGRAM,0);
    if(sockfd<0)
        ERR_EXIT("socket");
    //2.从键盘循环的读取数据
    char buf[1024]={0};
    while(1){
        socklen_t len=sizeof(server);
        printf("please enter:>   ");
        fflush(stdout);
        ssize_t read_size= read(0,buf,sizeof(buf)-1);
        //3.把读到的数据发送给服务器
        if(read_size>0){
            buf[read_size-1] = 0;//read是读到换行结束的,故会多读一个字符
            sendto(sockfd,buf,strlen(buf),0,\
                    (sockaddr*)&server,sizeof(server));
            ssize_t s=recvfrom(sockfd,buf,sizeof(buf)-1,0,\
                    (sockaddr*)&server,&len);
            //4.把服务器发送的数据显示到屏幕上
            if(s>0){
                buf[s]=0;
                printf("serevr echo:>  %s\n",buf);
            }
        }
    }
    return 0;
}

运行结果:
这里写图片描述

2.实现一个客户端与服务器之间的通信,客户端给服务器发送消息,服务器的作用是接收到客户端发给自己的信息,再给客户端回复消息

server.c (服务器端)

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<sys/types.h>
#include<sys/socket.h>
typedef struct sockaddr sockaddr;
typedef struct sockaddr_in sockaddr_in;

#define ERR_EXIT(m)\
    do\
{\
    perror(m);\
    exit(EXIT_FAILURE);\
}while(0)

void Usage(){
    printf("Usage ./server [ip] [port]\n");
    return;
}
int main(int argc,char*argv[]){
    if(3!=argc){
        Usage();
        return 1;
    }
    sockaddr_in local;
    local.sin_family=AF_INET;
    local.sin_addr.s_addr=inet_addr(argv[1]);
    local.sin_port=htons(atoi(argv[2]));
    //1.创建套接字
    int sockfd= socket(AF_INET,SOCK_DGRAM,0);
    if(sockfd<0)
        ERR_EXIT("socket");
    //2.进行绑定
    int ret= bind(sockfd,(sockaddr*)&local,sizeof(local));
    if(ret<0)
        ERR_EXIT("bind"); 
    //3.循环的进行客户端与服务器之间的通信
    char buf[1024]={0};
    sockaddr_in client;
    while(1){
        socklen_t len=sizeof(client);
        //接收客户端发送的数据,并把发送的数据输出到屏幕
        ssize_t s=recvfrom(sockfd,buf,sizeof(buf)-1,0,\
                (sockaddr*)&client,&len);
        if(s>0) {
            buf[s]=0;
            printf("client [%s: %d] say:> %s\n",inet_ntoa(client.sin_addr),\
                    ntohs(client.sin_port),buf);
            //给客户端发送消息
            memset(buf,0,sizeof(buf));
            printf("please enter:>  ");
            fflush(stdout);
            ssize_t read_size = read(0,buf,sizeof(buf)-1);
            printf("please wait......\n");
            if(read_size>0){
                buf[read_size-1]=0;
                sendto(sockfd,buf,strlen(buf),0,\
                        (sockaddr*)&client,sizeof(client));
            }
        }
    }
    return 0;
}

client.c(客户机端)

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<netinet/in.h>
typedef struct sockaddr sockaddr;
typedef struct sockaddr_in sockaddr_in;

#define ERR_EXIT(m)\
    do\
{\
    perror(m);\
    exit(EXIT_FAILURE);\
}while(0)

void Usage(){
    printf("Usage ./client [ip] [port]\n");
    return;
}
int main(int argc,char* argv[]){
    if(3!=argc){
        Usage();
        return 1;
    }
    sockaddr_in server;
    server.sin_family=AF_INET;
    server.sin_addr.s_addr=inet_addr(argv[1]);
    server.sin_port=htons(atoi(argv[2]));
    //1.创建套接字
    int sockfd=socket(AF_INET,SOCK_DGRAM,0);
    if(sockfd<0)
        ERR_EXIT("socket");
    //2.从键盘循环的读取数据
    char buf[1024]={0};
    while(1){
        socklen_t len=sizeof(server);
        printf("please enter:>   ");
        fflush(stdout);
        ssize_t read_size= read(0,buf,sizeof(buf)-1);
        //3.把读到的数据发送给服务器
        if(read_size>0){
            buf[read_size-1] = 0;//read是读到换行结束的,故会多读一个字符
            sendto(sockfd,buf,strlen(buf),0,\
                    (sockaddr*)&server,sizeof(server));
            printf("please wait......\n");
            ssize_t s=recvfrom(sockfd,buf,sizeof(buf)-1,0,\
                    (sockaddr*)&server,&len);
            //4.把服务器发送的数据显示到屏幕上
            if(s>0){
                buf[s]=0;
                printf("serevr say:>  %s\n",buf);
            }
        }
    }
    return 0;
}

运行结果:
这里写图片描述

IP地址

0:表示服务器可关联任意的地址
127.0.0.1:此IP地址是环回地址,是留给用户使用的

相关函数的用法请参考博客:
https://blog.csdn.net/dangzhangjing97/article/details/80280770
IP地址和端口请参考博客:
https://blog.csdn.net/dangzhangjing97/article/details/80280254

猜你喜欢

转载自blog.csdn.net/dangzhangjing97/article/details/80316519