linux网络编程学习1

ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,  struct sockaddr *src_addr, socklen_t *addrlen);

 The argument addrlen  is a value-result argument, which the caller should initialize before the call to the size of the  buffer  associated  with   src_addr,  and  modified on return to indicate the actual size of the source address.  

注意recvfrom的addrlen这个参数,使用前需要初始化为src_addr的大小,调用完毕后会被修改。

addrlen没有初始化时会出现从src_addr获得的ip地址为0的情况。


一个示例代码:


server端:

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>


#define MY_SERVER_PORT  4444
#define MAX_BUF_LEN     1024
int main(int argc, char *argv[])
{


    if (argc < 3) 
    {
        printf("please input ip and port.\r\n");
        return 0;
    }


    printf("server is %s:%s\r\n", argv[1], argv[2]);
    //create socket
    int sk = socket(AF_INET, SOCK_DGRAM, 0);
    if (sk < 0 )
    {
        printf("create socket error.\r\n");
        return -1;
    }


    //bind ip
    struct sockaddr_in serv_addr;
    memset(&serv_addr, 0, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(atoi(argv[2]));
    //inet_aton(argv[1], &serv_addr.sin_addr);   
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);   
    int ret = bind(sk, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
    if (0 != ret)
    {
        printf("bind error.\r\n");
        return 0;
    }

    char recv_buf[MAX_BUF_LEN];
    size_t recv_len; 
    struct sockaddr_in src_addr;
    socklen_t src_addr_len = sizeof(src_addr); 
    int i = 0;
    while(1)
    {
        recvfrom(sk, (void *)recv_buf, MAX_BUF_LEN, 0, (struct sockaddr *)&src_addr, &src_addr_len);
        //printf("[server recv] %s", recv_buf);
        printf("[server recv from %s:%d] %s", inet_ntoa(src_addr.sin_addr), ntohs(src_addr.sin_port), recv_buf);
        //printf("[server recv from %d:%d] %s", ntohl(src_addr.sin_addr.s_addr), ntohs(src_addr.sin_port), recv_buf);
        sprintf(recv_buf, "server count = %d\r\n", i);
        sendto(sk, (void *)recv_buf, MAX_BUF_LEN, 0, (struct sockaddr *)&src_addr, src_addr_len); 
        printf("[server send to %s:%d] %s", inet_ntoa(src_addr.sin_addr), (int)ntohs(src_addr.sin_port), recv_buf);
        //printf("[server send to %s:%d] %s", inet_ntoa(src_addr.sin_addr), (int)ntohs(src_addr.sin_port), recv_buf);
        i ++;
    }


    return 0;
}


client端:

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>


#define MAX_BUF_LEN    64 


int main(int argc, char *argv[])
{


    if (argc < 3) 
    {
        printf("please input ip and port.\r\n");
        return 0;
    }


    printf("server is %s:%s\r\n", argv[1], argv[2]);
    //create socket
    int sk = socket(AF_INET, SOCK_DGRAM, 0);
    if (sk < 0 )
    {
        printf("create socket error.\r\n");
        return -1;
    }


    //bind ip
    
    struct sockaddr_in src_addr;
    memset(&src_addr, 0, sizeof(src_addr));
    src_addr.sin_family = AF_INET;
    src_addr.sin_port = htons(atoi(argv[2]));
    src_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    socklen_t src_addr_len; 
    int i = 0;


    //client端的bind可以没有
    /*int ret = bind(sk, (struct sockaddr *)&src_addr, sizeof(src_addr));

    if (0 != ret)
    {

        printf("bind error.\r\n");
        return 0;
    }*/
    

    
    struct sockaddr_in serv_addr;
    memset(&serv_addr, 0, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(atoi(argv[2]));
    inet_aton(argv[1], &serv_addr.sin_addr);   
    

    //无连接的socket不能listen(listen后表示可以accept),但可以connect

    int ret = connect(sk, (struct sockaddr *)&serv_addr, (socklen_t)sizeof(serv_addr));

    if (ret < 0 )
    {
        printf("connect error\r\n");
        return 0;
    }


    char send_buf[MAX_BUF_LEN];
    size_t send_len; 
    while(1)
    {
        sprintf(send_buf, "client count = %d\r\n", i);
        //sendto(sk, (void *)send_buf, (size_t)strlen(send_buf), 0, (struct sockaddr *)&serv_addr, sizeof(serv_addr)); 
        write(sk, (void *)send_buf, MAX_BUF_LEN); 
        printf("[client send] %s", send_buf); 
        //recvfrom(sk, (void *)send_buf, send_len, 0, (struct sockaddr *)&dest_addr, &dest_addr_len);
        //recv(sk, (void *)send_buf, send_len, 0);
        read(sk, (void *)send_buf, MAX_BUF_LEN);
        printf("[client recv] %s", send_buf);
        //printf("[client recv] %s", send_buf);
        i ++;      
        sleep(1); 
    }


    return 0;
}


还有一个小问题,server端是用aliyun测试的,开始时是在本机编译后上传到aliyun,程序无法运行,后来把源代码传上去后编译,可以运行。

应该是因为aliyun服务器与自己的本地机器不同。本地机器是32位的,aliyun服务器是64位的。

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 、4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合;、下载 4使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合;、 4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值