linux udp网络通信

  • recvform函数
#include <sys/types.h>
#include <sys/socket.h>
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *from, int *fromlen);
返回:大于0-成功接收数据长度;-1-出错;
UDP套接字使用无连接协议,因此必须使用recvfrom函数,指明源地址;本函数从(已连接)套接口上接收数据,并捕获数据发送源的地址。
flags是传输控制标志,其值定义如下:
0:常规操作,如同read()函数;
from 和 fromlen 是“数据源地址-长度”参数。
  • sendto函数
#include <sys/types.h>
#include <sys/socket.h>
ssize_t sendto(int sockfd, const void *msg, size_t len, int flags, const struct sockaddr *to, int tolen);
        返回:大于0-成功发送数据长度;-1-出错;
UDP套接字使用无连接协议,因此必须使用sendto函数,指明目的地址;
flags是传输控制标志,其值定义如下:
0:常规操作,如同write()函数;

代码实战

/*udpclient.c*/
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include<stdlib.h>
#include<errno.h>
int main(int argc, char *argv[]) 
{   
    int fd; 
    struct sockaddr_in server,peer; 
    char rbuf[100]; 
    socklen_t len;
    int num;

    if (argc !=3) 
    { 
        printf("Usage: %s <IP Address> <message>\n", argv[0]); 
        exit(1); 
    } 
    fd=socket(AF_INET, SOCK_DGRAM, 0);
    if (fd==-1)
    { 
        perror("socket"); 
        exit(1);   
    } 
    bzero(&server,sizeof(server));
    server.sin_family = AF_INET; 
    server.sin_port = htons(1234);  
    server.sin_addr.s_addr = inet_addr(argv[1]); 
        
    //发送数据
    num=sendto(fd,argv[2],strlen(argv[2]),0,(struct sockaddr *)&server,sizeof(server));
    printf("client send %d bytes\n",num);
    len=sizeof(server);
    while(1)
    {
        //if(strncmp(argv[2],"bye",3)==0)
        //  break;
        //接收数据
        num=recvfrom(fd,rbuf,sizeof(rbuf),0,(struct sockaddr *)&peer,&len);
        if(num==-1) 
        {  
            printf("recvfrom errno is %d\n",errno);  
            break;  
        }
        rbuf[num]='\0';
        //比较是否是服务器地址
        // memcmp是比较内存区域buf1和buf2的前count个字节。该函数是按字节比较的。
        if(len != sizeof(server)  || memcmp(&server,&peer,len)!=0)
        {   
            printf("message not from server!\n");    
            continue;    
        }

        //输出信息
        printf("server message:%s.\n",rbuf);
        break;
    }
    close(fd);
}
/*udpserver.c*/
#include <sys/socket.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include<stdlib.h>
int main(void)
{
    int sockfd;
    struct sockaddr_in  server,client;
    int port = 1234;
    int opt = SO_REUSEADDR;
    int rt;
    int addrlen;
    char sendbuf[100];
    char rbuf[100];
    int num;

    sockfd=socket(AF_INET,SOCK_DGRAM,0);
    if(sockfd==-1)
    {
        perror("socket");
        exit(1);
    }
    
    //避免出现地址已经使用的错误 
    setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));

    bzero(&server,sizeof(server));
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = inet_addr("127.0.0.1"); //回送地址,指本地机,一般用来测试使用
    server.sin_port = htons(port);
    rt=bind(sockfd, (struct sockaddr *)& server, sizeof(server));
    if (rt== -1)
    {   
        perror("bind");
        exit(1);
    }

    addrlen=sizeof(client);
    while(1)
    {   //接收客户端信息
        num=recvfrom(sockfd,rbuf,sizeof(rbuf),0,(struct sockaddr *)&client,&addrlen);
        if(num<0)   
        {  
            perror("recvfrom");  
            break;   
        }
        rbuf[num]='\0';

        //显示客户端信息,如果客户端发来bye则退出循环
        printf("Got a message <%s> from client.\nIt's IP is %s,port is %d.\n", rbuf,inet_ntoa(client.sin_addr),ntohs(client.sin_port));
        if(strcmp(rbuf,"bye")==0)     
            break;
        //向客户端发送welcome 
        sprintf(sendbuf,"welcome!");               
        num=sendto(sockfd,sendbuf,strlen(sendbuf),0,(struct sockaddr *)&client,addrlen);
        printf("server send %d bytes\n",num);
    }
    close(sockfd);
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容