UDP协议双向通信

//服务器
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <stdlib.h>

#define DEST_IP "192.168.1.224" // ubuntu
#define DEST_PORT 60000
#define DEST_IP1 "192.168.1.224" // ubuntu
#define DEST_PORT1 60001

struct coll_package
{
    struct sockaddr_in client_addr; //存储客户端的地址和端口
    struct sockaddr_in dest_addr;
    socklen_t address_len;
    int socket_fd;


};
/*
    接收端
*/
void * udp_rev(void *arg)
{   
    struct coll_package cl = *(struct coll_package *)arg;
    char buf[1024] = {0};
    int ret;
    char *ip;
    int port ;
    while(1)
    {
        memset(buf,0,sizeof(buf));
        ret = recvfrom(cl.socket_fd,buf,sizeof(buf),0,(struct sockaddr *)&(cl.client_addr),&cl.address_len);
        if(ret < 0)
        {
            perror("recvfrom fail");
            return NULL;
        }
        if(strcmp(buf,"byebye")==0)
        {
            exit(0);
        }
        ip = inet_ntoa((cl.client_addr).sin_addr);
        port = ntohs((cl.client_addr).sin_port);
        printf("[%d][%s]recvfrom ok buf:%s ret:%d\n",port,ip,buf,ret);
       
    }

    
}
int main(int argc,char **argv)
{
    int ret = 0;
    pthread_t pid;
    struct coll_package cl;
    // 建立套接字
    int socket_fd = socket(AF_INET, SOCK_DGRAM, 0);
    if (socket_fd < 0)
    {
        perror("socket fail");
        return -1;
    }

    // 所以设置端口号可以复用,这两条语句放在 绑定bind 之前
    int optval = 1;
    setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
    
    // 绑定本机ip和端口(用来接收数据)
    struct sockaddr_in dest_addr;
    dest_addr.sin_family = AF_INET;                 // ipv4
    dest_addr.sin_port = htons(DEST_PORT);          // 本机端口转网络端口
    dest_addr.sin_addr.s_addr = inet_addr(DEST_IP); // 本机ip转网络ip
    ret = bind(socket_fd, (struct sockaddr *)&dest_addr, sizeof(dest_addr));
    if (ret < 0)
    {
        perror("bind fail");
        return -1;
    }
    printf("绑定本机成功[%d][%s]\n", DEST_PORT, DEST_IP);

    // 接收数据
   
    cl.client_addr.sin_family = AF_INET;                 // ipv4
    cl.client_addr.sin_port = htons(DEST_PORT1);          // 本机端口转网络端口
    cl.client_addr.sin_addr.s_addr = inet_addr(DEST_IP1); // 本机ip转网络ip

    socklen_t address_len = sizeof(cl.client_addr);
    char buf[1024] = {0};
    cl.socket_fd = socket_fd;
    cl.dest_addr = dest_addr;
    cl.address_len = address_len;
    char *ip;
    int port;
    pthread_create(&pid,NULL,udp_rev,(void*)&cl);
    while (1)
    {
        printf("给服务器发送信息\n");
        scanf("%s",buf);
        ret=sendto(socket_fd,buf, strlen(buf), 0, (struct sockaddr *)&cl.client_addr, sizeof(dest_addr));
        ip = inet_ntoa((cl.client_addr).sin_addr);
        port = ntohs((cl.client_addr).sin_port);
       if(strcmp(buf,"byebye")==0)
        {
            exit(0);
        }
        sleep(1);
    }

    // 关闭套接字
    close(socket_fd);

    return 0;
}


//

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <stdlib.h>


#define DEST_IP "192.168.1.224" // ubuntu
#define DEST_PORT 60001
#define DEST_IP1 "192.168.1.224" // ubuntu
#define DEST_PORT1 60000

struct coll_package
{
    struct sockaddr_in client_addr; //存储客户端的地址和端口
    struct sockaddr_in dest_addr;
    socklen_t address_len;
    int socket_fd;


};
/*
    接收端
*/
void * udp_rev(void *arg)
{   
    struct coll_package cl = *(struct coll_package *)arg;
    char buf[1024] = {0};
    int ret;
    char *ip;
    int port ;
    while(1)
    {
        memset(buf,0,sizeof(buf));
        ret = recvfrom(cl.socket_fd,buf,sizeof(buf),0,(struct sockaddr *)&(cl.client_addr),&cl.address_len);
        if(ret < 0)
        {
            perror("recvfrom fail");
            return NULL;
        }
        if(strcmp(buf,"byebye")==0)
        {
            exit(0);
        }
        ip = inet_ntoa((cl.client_addr).sin_addr);
        port = ntohs((cl.client_addr).sin_port);
        printf("[%d][%s]recvfrom ok buf:%s ret:%d\n",port,ip,buf,ret);
       
    }

    
}
int main(int argc,char **argv)
{
    int ret = 0;
    pthread_t pid;
    struct coll_package cl;
    // 建立套接字
    int socket_fd = socket(AF_INET, SOCK_DGRAM, 0);
    if (socket_fd < 0)
    {
        perror("socket fail");
        return -1;
    }

    // 所以设置端口号可以复用,这两条语句放在 绑定bind 之前
    int optval = 1;
    setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
    
    // 绑定本机ip和端口(用来接收数据)
    struct sockaddr_in dest_addr;
    dest_addr.sin_family = AF_INET;                 // ipv4
    dest_addr.sin_port = htons(DEST_PORT);          // 本机端口转网络端口
    dest_addr.sin_addr.s_addr = inet_addr(DEST_IP); // 本机ip转网络ip
    ret = bind(socket_fd, (struct sockaddr *)&dest_addr, sizeof(dest_addr));
    if (ret < 0)
    {
        perror("bind fail");
        return -1;
    }
    printf("绑定本机成功[%d][%s]\n", DEST_PORT, DEST_IP);
    cl.client_addr.sin_family = AF_INET;                 // ipv4
    cl.client_addr.sin_port = htons(DEST_PORT1);          // 本机端口转网络端口
    cl.client_addr.sin_addr.s_addr = inet_addr(DEST_IP1); // 本机ip转网络ip

    socklen_t address_len = sizeof(cl.client_addr);
    char buf[1024] = {0};
    cl.socket_fd = socket_fd;
    cl.dest_addr = dest_addr;
    cl.address_len = address_len;
    char *ip;
    int port;
    pthread_create(&pid,NULL,udp_rev,(void*)&cl);
    while (1)
    {
        printf("给客户端发送信息\n");
        scanf("%s",buf);
        ret=sendto(socket_fd,buf, strlen(buf), 0, (struct sockaddr *)&cl.client_addr, sizeof(dest_addr));
        ip = inet_ntoa((cl.client_addr).sin_addr);
        port = ntohs((cl.client_addr).sin_port);
        if(strcmp(buf,"byebye")==0)
        {
            exit(0);
        }
        sleep(1);
    }

    // 关闭套接字
    close(socket_fd);

    return 0;
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值