Linux 网络编程详解十二

UDP的特点
--无连接
--基于消息的数据传输服务
--不可靠
--UDP更加高效
UDP注意点
--UDP报文可能会丢失,重复
--UDP报文可能会乱序
--UDP缺乏流量控制(UDP缓冲区写满之后,没有流量控制,会覆盖缓冲区)
--UDP协议数据报文截断(如果接收到的数据报文大于缓冲区,报文可以被截断,后面部分丢失)
--recvfrom返回0,不代表连接关闭(实际上UDP是无连接的),sendto可以发送数据0包,只含有UDP头部
--UDP客户端也可以调用connect,但是并没有完成三次握手,只是维护了一个状态信息(和对等方的)
--一旦调用了connect,就可以使用send函数
//UDP协议客户端
#define SETNO 0

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

/**
 * clear_back - 退格不回显
 * 成功返回0,失败返回-1
 * */
int clear_back()
{
    struct termios term;
    memset(&term, 0, sizeof(term));
    //获取当前系统设置
    if (tcgetattr(STDIN_FILENO, &term) == -1)
    {
        perror("tcgetattr() err");
        return -1;
    }
    //修改系统设置
    term.c_cc[VERASE] = '\b';
    //立即生效
    if (tcsetattr(STDIN_FILENO, TCSANOW, &term) == -1)
    {
        perror("tcgetattr() err");
        return -1;
    }
    return 0;
}

int main(int arg, char *args[])
{
    if(clear_back()!=0)
        return -1;
    int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd == -1)
    {
        perror("socket() err");
        return -1;
    }
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(8080);
    //连接的服务器地址
    addr.sin_addr.s_addr = inet_addr("127.0.0.1");
#if SETNO==0
    /*
     * UDP客户端也可以调用connect,但是并没有完成三次握手,
     * 只是维护了一个状态信息(和对等方的),所以发送报文时,不需要传服务器ip*/
     if(connect(sockfd,(struct sockaddr *)&addr,sizeof(addr))==-1)
     {
     perror("connect() err");
     return -1;
     }
#endif
    char buf[1024] = { 0 };
    int rc = 0;
    while (fgets(buf, 1024, stdin) != NULL)
    {
#if SETNO==0
        rc = send(sockfd, buf,strlen(buf),0);
#else
        rc = sendto(sockfd, buf, strlen(buf), 0, (struct sockaddr *) &addr,
                        sizeof(addr));
#endif

        if (rc == -1)
        {
            perror("sendto() err");
            break;
        }
        memset(buf, 0, 1024);
        rc = recvfrom(sockfd, buf, 1024, 0, NULL, NULL);
        if (rc == -1)
        {
            perror("recvfrom() err");
            break;
        }
        fputs(buf, stdout);
        memset(buf, 0, 1024);
    }
    return 0;
}
//UDP协议服务器端
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main(int arg, char *args[])
{
    int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd == -1)
    {
        perror("socket() err");
        return -1;
    }
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(8080);
    //绑定本地IP地址
    addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    if (bind(sockfd, (struct sockaddr *) &addr, sizeof(addr)) == -1)
    {
        perror("bind() err");
        return -1;
    }
    int rc = 0;
    char buf[1024] = { 0 };
    struct sockaddr_in peeraddr;
    socklen_t peerlen = sizeof(peeraddr);
    while (1)
    {
        memset(buf,0,sizeof(buf));
        do
        {
            rc = recvfrom(sockfd, buf, 2, 0, (struct sockaddr *) &peeraddr,
                    &peerlen);
        } while (rc == -1 && errno == EINTR);
        if (rc == -1)
        {
            perror("recvfrom() err");
            break;
        }
        //fputs()函数必须以'\n'结尾才会打印在终端上,,否则需要清空缓冲区
        fputs(buf, stdout);
        fflush(stdout);
        //发送数据
        rc = sendto(sockfd, buf, rc, 0, (struct sockaddr *) &peeraddr,
                sizeof(peeraddr));
        if (rc == -1)
        {
            perror("sendto() err");
            break;
        }
    }
    return 0;
}
.SUFFIXES:.c .o
CC=gcc
SRCS=hello.c
OBJS=$(SRCS:.c=.o)
EXEC=ser
SRCS1=tec01.c
OBJS1=$(SRCS1:.c=.o)
EXEC1=clt

start:$(OBJS) $(OBJS1)
    $(CC) -o $(EXEC) $(OBJS)
    $(CC) -o $(EXEC1) $(OBJS1)
    @echo "^_^-----OK------^_^"
.c.o:
    $(CC) -Wall -g -o $@ -c $<
clean:
    rm -f $(OBJS)
    rm -f $(EXEC)

 

posted on 2016-12-15 16:07  寒魔影  阅读(335)  评论(0编辑  收藏  举报

导航