天天看點

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()

void Usage(){
    printf("Usage ./server [ip] [port]\n");
    return;
}
int main(int argc,char*argv[]){
    if(!=argc){
        Usage();
        return ;
    }
    sockaddr_in local;
    local.sin_family=AF_INET;
    local.sin_addr.s_addr=inet_addr(argv[]);
    local.sin_port=htons(atoi(argv[]));
    //1.建立套接字
    int sockfd= socket(AF_INET,SOCK_DGRAM,);
    if(sockfd<)
        ERR_EXIT("socket");
    //2.進行綁定
    int ret= bind(sockfd,(sockaddr*)&local,sizeof(local));
    if(ret<)
        ERR_EXIT("bind"); 
    //3.循環的把用戶端發送的資料,給用戶端發送回去
    char buf[]={};
    sockaddr_in client;
    while(){
        socklen_t len=sizeof(client);
        ssize_t s=recvfrom(sockfd,buf,sizeof(buf)-,,\
                (sockaddr*)&client,&len);
        if(s>) {
            buf[s]=;
            printf("client [%s: %d] say:> %s\n",inet_ntoa(client.sin_addr),\
                    ntohs(client.sin_port),buf);
            sendto(sockfd,buf,strlen(buf),,\
                    (sockaddr*)&client,sizeof(client));
        }
    }
    return ;
}
           

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()

void Usage(){
    printf("Usage ./client [ip] [port]\n");
    return;
}
int main(int argc,char* argv[]){
    if(!=argc){
        Usage();
        return ;
    }
    sockaddr_in server;
    server.sin_family=AF_INET;
    server.sin_addr.s_addr=inet_addr(argv[]);
    server.sin_port=htons(atoi(argv[]));
    //1.建立套接字
    int sockfd=socket(AF_INET,SOCK_DGRAM,);
    if(sockfd<)
        ERR_EXIT("socket");
    //2.從鍵盤循環的讀取資料
    char buf[]={};
    while(){
        socklen_t len=sizeof(server);
        printf("please enter:>   ");
        fflush(stdout);
        ssize_t read_size= read(,buf,sizeof(buf)-);
        //3.把讀到的資料發送給伺服器
        if(read_size>){
            buf[read_size-] = ;//read是讀到換行結束的,故會多讀一個字元
            sendto(sockfd,buf,strlen(buf),,\
                    (sockaddr*)&server,sizeof(server));
            ssize_t s=recvfrom(sockfd,buf,sizeof(buf)-,,\
                    (sockaddr*)&server,&len);
            //4.把伺服器發送的資料顯示到螢幕上
            if(s>){
                buf[s]=;
                printf("serevr echo:>  %s\n",buf);
            }
        }
    }
    return ;
}
           

運作結果:

linux:套接字程式設計 UDP

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()

void Usage(){
    printf("Usage ./server [ip] [port]\n");
    return;
}
int main(int argc,char*argv[]){
    if(!=argc){
        Usage();
        return ;
    }
    sockaddr_in local;
    local.sin_family=AF_INET;
    local.sin_addr.s_addr=inet_addr(argv[]);
    local.sin_port=htons(atoi(argv[]));
    //1.建立套接字
    int sockfd= socket(AF_INET,SOCK_DGRAM,);
    if(sockfd<)
        ERR_EXIT("socket");
    //2.進行綁定
    int ret= bind(sockfd,(sockaddr*)&local,sizeof(local));
    if(ret<)
        ERR_EXIT("bind"); 
    //3.循環的進行用戶端與伺服器之間的通信
    char buf[]={};
    sockaddr_in client;
    while(){
        socklen_t len=sizeof(client);
        //接收用戶端發送的資料,并把發送的資料輸出到螢幕
        ssize_t s=recvfrom(sockfd,buf,sizeof(buf)-,,\
                (sockaddr*)&client,&len);
        if(s>) {
            buf[s]=;
            printf("client [%s: %d] say:> %s\n",inet_ntoa(client.sin_addr),\
                    ntohs(client.sin_port),buf);
            //給用戶端發送消息
            memset(buf,,sizeof(buf));
            printf("please enter:>  ");
            fflush(stdout);
            ssize_t read_size = read(,buf,sizeof(buf)-);
            printf("please wait......\n");
            if(read_size>){
                buf[read_size-]=;
                sendto(sockfd,buf,strlen(buf),,\
                        (sockaddr*)&client,sizeof(client));
            }
        }
    }
    return ;
}
           

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()

void Usage(){
    printf("Usage ./client [ip] [port]\n");
    return;
}
int main(int argc,char* argv[]){
    if(!=argc){
        Usage();
        return ;
    }
    sockaddr_in server;
    server.sin_family=AF_INET;
    server.sin_addr.s_addr=inet_addr(argv[]);
    server.sin_port=htons(atoi(argv[]));
    //1.建立套接字
    int sockfd=socket(AF_INET,SOCK_DGRAM,);
    if(sockfd<)
        ERR_EXIT("socket");
    //2.從鍵盤循環的讀取資料
    char buf[]={};
    while(){
        socklen_t len=sizeof(server);
        printf("please enter:>   ");
        fflush(stdout);
        ssize_t read_size= read(,buf,sizeof(buf)-);
        //3.把讀到的資料發送給伺服器
        if(read_size>){
            buf[read_size-] = ;//read是讀到換行結束的,故會多讀一個字元
            sendto(sockfd,buf,strlen(buf),,\
                    (sockaddr*)&server,sizeof(server));
            printf("please wait......\n");
            ssize_t s=recvfrom(sockfd,buf,sizeof(buf)-,,\
                    (sockaddr*)&server,&len);
            //4.把伺服器發送的資料顯示到螢幕上
            if(s>){
                buf[s]=;
                printf("serevr say:>  %s\n",buf);
            }
        }
    }
    return ;
}
           

運作結果:

linux:套接字程式設計 UDP

IP位址

0:表示伺服器可關聯任意的位址

127.0.0.1:此IP位址是環回位址,是留給使用者使用的

相關函數的用法請參考部落格:

https://blog.csdn.net/dangzhangjing97/article/details/80280770

IP位址和端口請參考部落格:

https://blog.csdn.net/dangzhangjing97/article/details/80280254

繼續閱讀