UDP server

学习网络编程时所写的一些代码,由于工作较忙,没太多功夫整理,也基本没有注释,如有疑问希望自己去查手册。这些程序都在linux下写的。

//使用recvmsg,和sendmsg进行收发

//udp-server2.c

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

#include <errno.h>
#define PORT 8848
#define BUFLEN 4096
typedef struct sockaddr sockaddr;
typedef struct sockaddr_in sockaddr_in;
typedef struct iovec iovec;
typedef struct msghdr msghdr;
typedef struct timeval timeval;
int main(int argc, char *argv[])
{
    int sockfd;
    sockaddr_in rev_addr, send_addr;
    sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if(sockfd<0)
    {
        printf("error for socket()\n");
        exit(1);
    }

    memset(&rev_addr, 0, sizeof(rev_addr));
    rev_addr.sin_family = AF_INET;
    rev_addr.sin_port = htons(PORT);
    rev_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    
    if(bind(sockfd, (sockaddr*)&rev_addr, sizeof(rev_addr)) < 0)
    {
        printf("error for bind()\n");
        close(sockfd);
        exit(1);
    }
    
    while(1)
    {
        msghdr mh;
        iovec iov;
        char buf[1024];
        int send_len = sizeof(send_addr);
        mh.msg_name = &send_addr;
        mh.msg_namelen = send_len;
        mh.msg_iov = &iov;
        mh.msg_iovlen = 1;
        mh.msg_iov->iov_base = buf;
        mh.msg_iov->iov_len = sizeof(buf);
        mh.msg_control = NULL;
        mh.msg_controllen = 0;
        mh.msg_flags = 0;
    
        int res;
    
        if((res = recvmsg(sockfd, &mh, 0))<0)
        {
            printf("error for recvmsg()%s\n", strerror(errno));
            close(sockfd);
            exit(1);
        }else
        {
            printf("receive from %s:%u size:%d\n",inet_ntoa(send_addr.sin_addr),
            ntohs(send_addr.sin_port), strlen(buf));
        }

    }
    return 0;
}

 

//udp-server.c

//使用recvfrom,和sendto进行收发,效果和recvmsg/sendmsg一致

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#define PORT 8848
#define BUFLEN 4096
int main(int argc, char *argv[])
{
    int sockfd;
    struct sockaddr_in my_addr;
    struct sockaddr_in dest_addr;
    char revbuf[BUFLEN];
    sockfd = socket(AF_INET, SOCK_DGRAM, 0);

    if(sockfd<0)
    {
        printf("error for socket()\n");
        exit(1);
    }

    memset(&my_addr, 0, sizeof(my_addr));
    my_addr.sin_family = AF_INET;
    my_addr.sin_port = htons(PORT);
    my_addr.sin_addr.s_addr = htonl(INADDR_ANY);//inet_addr("200.200.30.14");

    
    if(bind(sockfd, (struct sockaddr*)&my_addr, sizeof(my_addr)) < 0)
    {
        printf("error for bind()\n");
        close(sockfd);
        exit(1);
   }
    while(1)
    {
        int revlen=0;
        int addr_len = sizeof(dest_addr);
    if((revlen=recvfrom(sockfd, revbuf, BUFLEN, 0,
     (struct sockaddr*)&dest_addr, &addr_len))<0)
    {
        printf("error for recvfrom()\n");
        close(sockfd);
        exit(1);
    }
    else
    {//打印源

     printf("receive from %s:%u\n",inet_ntoa(dest_addr.sin_addr),
        ntohs(dest_addr.sin_port));
     /*struct sockaddr_in name;//打印其他数据信息
     int len = sizeof(name);
     getsockname(sockfd, (struct sockaddr*)&name, &len);
     printf("sockname %s:%u\n", inet_ntoa(name.sin_addr),
        ntohs(name.sin_port));
     memset(&name, 0, sizeof(name));
     getpeername(sockfd, (struct sockaddr*)&name, &len);
        printf("peername %s:%u\n", inet_ntoa(name.sin_addr),
            ntohs(name.sin_port));*/


    }
    if(sendto(sockfd, revbuf, revlen, 0,
     (struct sockaddr*)&dest_addr, sizeof(dest_addr))!=revlen)
    {
     printf("error for sendto()\n");
     close(sockfd);
     exit(1);
    }
    else
    { //打印目的地

     printf("send to %s:%u\n", inet_ntoa(dest_addr.sin_addr),
            ntohs(dest_addr.sin_port));
    }
    }
    return 0;
}

 

 

 

//rudp-server2.c

//rawsocket + sendto/recvfrom+修改头部

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

#define BUFLEN 4096
#define PORT 8848
typedef struct ip_hdr{
    unsigned int ip_length:4; /*little-endian*/
    unsigned int ip_version:4;
    unsigned char ip_tos;
    unsigned short ip_total_length;
    unsigned short ip_id;
    unsigned short ip_flags;
    unsigned char ip_ttl;
    unsigned char ip_protocol;
    unsigned short ip_cksum;
    unsigned int ip_source;
    unsigned int ip_dest;
}ip_hdr;
typedef struct udp_hdr{
    unsigned short s_port;
    unsigned short d_port;
    unsigned short length;
    unsigned short cksum;
}udp_hdr;

typedef struct psd_header{//伪头部,用于计算校验和

    unsigned int s_ip;//source ip

    unsigned int d_ip;//dest ip

    unsigned char mbz;//0

    unsigned char proto;//proto type

    unsigned short plen;//length

}psd_header;

void swap(unsigned int *a, unsigned int *b)
{
    *a = (*a)^(*b);
    *b = (*a)^(*b);
    *a = (*a)^(*b);
}

unsigned short checksum(unsigned short* buffer, int size)
{
    unsigned long cksum = 0;
    while(size>1)
    {
    cksum += *buffer++;
    size -= sizeof(unsigned short);
    }
    if(size)
    {
    cksum += *(unsigned char*)buffer;
    }
    cksum = (cksum>>16) + (cksum&0xffff); //将高16bit与低16bit相加

    cksum += (cksum>>16); //将进位到高位的16bit与低16bit 再相加

    return (unsigned short)(~cksum);
}
int main(int argc, char *argv[])
{
    char revbuf[BUFLEN];
    int sockfd = -1;
    
    struct sockaddr_in host_addr;
    if((sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_UDP))<0)
    {
    printf("socket() error!\n");
    exit(1);
    }
    memset(&host_addr, 0, sizeof(host_addr));
    host_addr.sin_family = AF_INET;
    host_addr.sin_port = htons(PORT);
    host_addr.sin_addr.s_addr = inet_addr("200.200.30.14");
    if(bind(sockfd, (struct sockaddr*)&host_addr, sizeof(host_addr))<0)
    {
    printf("error for bind()%s\n", strerror(errno));
    close(sockfd);
    exit(1);
    }
    
    const int on = 1;
    if(setsockopt(sockfd, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on))<0)
    {
    printf("setsockopt() error!\n");
    exit(0);    
    }
    
    int addr_len = sizeof(host_addr);

    while(1)
    {    
        int revlen=0;
        memset(&host_addr, 0, sizeof(host_addr));
        int addr_len = sizeof(host_addr);
        if((revlen = recvfrom(sockfd, revbuf, BUFLEN, 0,
            (struct sockaddr*)&host_addr, &addr_len))<0)
        {
            printf("recvfrom() error!\n");
            close(sockfd);
            exit(1);
        }else{
    
            udp_hdr *udphdr;
            udphdr = (udp_hdr*)(revbuf+20);
            if(udphdr->d_port^htons(PORT))
                continue;
            printf("receive from %s:%d\n", inet_ntoa(host_addr.sin_addr),
                ntohs(host_addr.sin_port));
            struct sockaddr_in name;
            int len;
            getsockname(sockfd, (struct sockaddr*)&name, &len);
            printf("sockname %s:%d\n", inet_ntoa(name.sin_addr),
                ntohs(name.sin_port));
            memset(&name, 0, sizeof(name));
            getpeername(sockfd, (struct sockaddr*)&name, &len);
            printf("peername %s:%u\n", inet_ntoa(name.sin_addr), ntohs(name.sin_port));
            ip_hdr *iphdr;
            iphdr = (ip_hdr*)revbuf;
            udp_hdr *udphdr1;
            udphdr1 = (udp_hdr*)(revbuf+20);
            swap(&(iphdr->ip_source), &(iphdr->ip_dest));
            unsigned short t = udphdr1->s_port;
            udphdr1->s_port = udphdr1->d_port;
            udphdr1->d_port = htons(ntohs(t)+1);
            
            char tmp4[ntohs(udphdr1->length)+sizeof(psd_header)];
            psd_header* ph = (psd_header*)tmp4;
            ph->d_ip=iphdr->ip_dest;
            ph->s_ip=iphdr->ip_source;
            ph->mbz=0;
            ph->proto = 0x11;
            ph->plen = udphdr1->length;
     //printf("udp header length %d\n", ntohs(udphdr1->length));

            memcpy((unsigned char*)ph+sizeof(psd_header), (unsigned char*)udphdr1, ntohs(udphdr1->length));
            udphdr1->cksum = 0;
            udphdr1->cksum = checksum((unsigned short*)(ph),
            ntohs(udphdr1->length)+sizeof(psd_header));
    
            printf("totallen %d bytes\n", ntohs(iphdr->ip_total_length));
    }
    if(sendto(sockfd, revbuf, revlen, 0,
     (struct sockaddr*)&host_addr, sizeof(host_addr))!=revlen)
    {
     printf("sendto() error, %s\n", strerror(errno));
     close(sockfd)%

 

 

//交叉使用recvmsg,sendto

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

#include <errno.h>
#define PORT 8848
#define BUFLEN 4096
typedef struct sockaddr sockaddr;
typedef struct sockaddr_in sockaddr_in;
typedef struct iovec iovec;
typedef struct msghdr msghdr;
typedef struct timeval timeval;
int main(int argc, char *argv[])
{
    int sockfd;
    sockaddr_in rev_addr, send_addr;
    sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
    if(sockfd<0)
    {
        printf("error for socket()\n");
        exit(1);
    }

    while(1)
    {
        msghdr mh;
        iovec iov;
        char buf[1024];
        int send_len = sizeof(send_addr);
        mh.msg_name = &send_addr;
        mh.msg_namelen = send_len;
        mh.msg_iov = &iov;
        mh.msg_iovlen = 1;
        mh.msg_iov->iov_base = buf;
        mh.msg_iov->iov_len = sizeof(buf);
        mh.msg_control = NULL;
        mh.msg_controllen = 0;
        mh.msg_flags = 0;
    
        int res;
    
        if((res = recvmsg(sockfd, &mh, 0))<0)
        {
            printf("error for recvmsg()%s\n", strerror(errno));
            close(sockfd);
            exit(1);
        }else
        {
            printf("receive from %s:%u %c\n",inet_ntoa(send_addr.sin_addr),
            ntohs(send_addr.sin_port), buf[28]);
        }


        if(sendto(sockfd, revbuf, revlen, 0,
            (struct sockaddr*)&dest_addr, sizeof(dest_addr))!=revlen)
        {
            printf("error for sendto()\n");
            close(sockfd);
            exit(1);
        }else
        {
            printf("send to %s:%u\n", inet_ntoa(dest_addr.sin_addr),
                ntohs(dest_addr.sin_port));
        }
    }
    return 0;
}

<script type=text/javascript charset=utf-8 src="http://static.bshare.cn/b/buttonLite.js#style=-1&uuid=&pophcol=3&lang=zh"></script> <script type=text/javascript charset=utf-8 src="http://static.bshare.cn/b/bshareC0.js"></script>
阅读(714) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~
评论热议
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值