Linux UDP编程(1)

来源:互联网 发布:js typeof function 编辑:程序博客网 时间:2024/05/20 09:21

下列测试是在两台机器上(服务端和客户端),编译运行

1. # gcc client.c -o client

client.c: 在函数‘main’中:
client.c:12: 错误:‘dest_addr’的存储大小未知

解决方案:
# gcc -E client.c | grep "struct sockaddr_in"
 struct sockaddr_in dest_addr;
首先预处理编译client.c,发现无头文件,说明头文件指定错误
实际struct sockaddr_in声明包含在下列头文件中
#include <arpa/inet.h>
#include <netinet/in.h> 

2. # gcc client.c -o client
#客户端
# ./client 
write error: Connection refused
send number:9

服务器端
#tcpdump -i eth0 host 192.168.60.136 and udp 

tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
16:49:38.927885 IP localhost.56296 > abc123.ndmp: UDP, length 1024
16:49:38.927940 IP localhost.56296 > abc123.ndmp: UDP, length 1024
16:49:38.927958 IP localhost.56296 > abc123.ndmp: UDP, length 1024
16:49:38.927973 IP localhost.56296 > abc123.ndmp: UDP, length 1024
16:49:38.927988 IP localhost.56296 > abc123.ndmp: UDP, length 1024
16:49:38.928005 IP localhost.56296 > abc123.ndmp: UDP, length 1024
16:49:38.928021 IP localhost.56296 > abc123.ndmp: UDP, length 1024
16:49:38.928028 IP localhost.56296 > abc123.ndmp: UDP, length 1024

上述没有运行server端,直接运行client端,可见系统发送一部分数据包。服务器端接收数据包

3.服务器端
# netstat -su
IcmpMsg:
    InType3: 55
    OutType3: 467
Udp:
    9617286 packets received
    375854 packets to unknown port received.
    108733 packet receive errors
    6663 packets sent
    RcvbufErrors: 108733
UdpLite:
IpExt:
    InMcastPkts: 12125
    OutMcastPkts: 209
    InBcastPkts: 24214
    OutBcastPkts: 18
    InOctets: 15042525827
    OutOctets: 108912059
    InMcastOctets: 2415162
    OutMcastOctets: 21128
    InBcastOctets: 3161452
    OutBcastOctets: 1404

#./server &

# netstat -su
IcmpMsg:
    InType3: 55
    OutType3: 467
Udp:
    9624946 packets received
    375854 packets to unknown port received.
    111096 packet receive errors
    6677 packets sent
    RcvbufErrors: 111096
UdpLite:
IpExt:
    InMcastPkts: 12139
    OutMcastPkts: 209
    InBcastPkts: 24261
    OutBcastPkts: 18
    InOctets: 15058618880
    OutOctets: 109265743
    InMcastOctets: 2417401
    OutMcastOctets: 21128
    InBcastOctets: 3165284
    OutBcastOctets: 1404

###########################
192.168.60.136,7637


#./client 
./client 
send number:10000

上述系统发生丢包现象, 发送10000,实际接受了7637,从而由此可见udp不可靠的,需要进行流量控制。

上述大部分内容,参考了<<Unix 网络编程>>



================================================================client.c 

//#include <arpa/inet.h>
//#include <netinet/in.h> 
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <stdio.h>
#include <strings.h>
int main()
{

        char buf[1024];
        int i=0;
        struct sockaddr_in dest_addr;

        int sockfd = socket(AF_INET,SOCK_DGRAM,0);
        int len =  sizeof(buf);

        bzero(&dest_addr,sizeof(dest_addr));
        dest_addr.sin_family=AF_INET;
        dest_addr.sin_port=htons(10000);
        dest_addr.sin_addr.s_addr=inet_addr("192.168.60.123");
        connect(sockfd,(struct sockaddr *)&dest_addr, sizeof(dest_addr));

        while(i<10000)
        {
                i++;
                int ret = sendto(sockfd, buf, len, 0, (struct sockaddr *)&dest_addr, sizeof(dest_addr));
                if (ret < 0)

                {
                        perror("write error");
                        break;
                }

        }
        printf("send number:%d\n",i);
}

=======================================================================server.c 

#include <arpa/inet.h>
#include <netinet/in.h>
int main()
{
        char buf[1024];
        int i=0;
        int fd = socket(AF_INET,SOCK_DGRAM,0);
        struct sockaddr_in dest_addr;

        bzero(&dest_addr,sizeof(dest_addr));
        socklen_t addrlen;
        dest_addr.sin_family=AF_INET;
        dest_addr.sin_port=htons(10000);
        dest_addr.sin_addr.s_addr=INADDR_ANY;
        bind(fd,(struct sockaddr*)&dest_addr,sizeof(dest_addr));

        while (1)
        {
                i++;
                int ret = recvfrom(fd, buf, 1024, 0,(struct sockaddr*) &dest_addr, &addrlen);
                if(ret < 0)
                {
                        perror("recvfrom");
                        break;
                }

                printf ("%s,%d\n", inet_ntoa (dest_addr.sin_addr), i);

        }
        printf ("%s,%d\n", inet_ntoa (dest_addr.sin_addr), i);
}
0 0