Socket编程实践(13) --UDP编程基础(1)

UDP特点

无连接,面向数据报(基于消息,不会粘包)的数据传输服务;

不可靠(可能会丢包),但一般情况下UDP更加高效;

 
 

UDP客户/服务基本模型

UDP基础API

1.Recvfrom

SYNOPSIS

       #include <sys/types.h>
       #include <sys/socket.h>
       ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
                        struct sockaddr *src_addr, socklen_t *addrlen);

2.Sendto

SYNOPSIS

       #include <sys/types.h>
       #include <sys/socket.h>
       ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);

实践:一个简陋的echo回声server/client

//server.cpp
#include "commen.h"

int main()
{
    //创建UDP socket
    int sockfd = socket(AF_INET,SOCK_DGRAM,0);
    if (sockfd == -1)
    {
        err_exit("socket error");
    }

    //填写server端信息
    struct sockaddr_in serverAddr;
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(9001);
    serverAddr.sin_addr.s_addr =INADDR_ANY;
    //绑定server端端口号
    if (bind(sockfd,(struct sockaddr *)&serverAddr,sizeof(serverAddr)) == -1)
    {
        err_exit("bind error");
    }

    char buf[BUFSIZ];
    struct sockaddr_in peerAddr;
    socklen_t peerLen = sizeof(peerAddr);

    while (true)
    {
        memset(buf,0,sizeof(buf));

        int readCount = 0;
        //接收从客户端发送过来的数据
        if ((readCount = recvfrom(sockfd,buf,sizeof(buf),0,(struct sockaddr *)&peerAddr,&peerLen)) == -1)
        {
            err_exit("recvfrom error");
        }
        //打印客户端信息
        cout << "Client: " << endl;
        cout << "\tsin_port: " << ntohs(peerAddr.sin_port) << endl;
        cout << "\tsin_addr: " << inet_ntoa(peerAddr.sin_addr) << endl;

        //将客户端发送来的信息回写回去
        if (sendto(sockfd,buf,sizeof(buf),0,(struct sockaddr *)&peerAddr,peerLen) == -1)
        {
            err_exit("sendto error");
        }

        buf[readCount] = 0;
        //输出到屏幕
        fputs(buf,stdout);
    }

    return 0;
}

//client.cpp
#include "commen.h"

int main()
{
    //创建UDP socket
    int sockfd = socket(AF_INET,SOCK_DGRAM,0);
    if (sockfd == -1)
    {
        err_exit("socket error");
    }

    //填写server端信息
    struct sockaddr_in serverAddr;
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(9001);
    serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");

    char buf[BUFSIZ];
    //从键盘接收数据
    while (fgets(buf,sizeof(buf),stdin) != NULL)
    {
        //向server端传送数据
        if (sendto(sockfd,buf,strlen(buf),0,(struct sockaddr *)&serverAddr,sizeof(serverAddr)) == -1)
        {
            err_exit("sendto error");
        }

        memset(buf,0,sizeof(buf));
        int readCount = 0;
        //从server端接收数据,并且忽略server端信息recvfrom(xx,xx,xx,xx,NULL,NULL)
        if ((readCount = recvfrom(sockfd,buf,sizeof(buf),0,NULL,NULL)) == -1)
        {
            err_exit("recvfrom error");
        }

        buf[readCount] = 0;
        //将数据写到屏幕
        fputs(buf,stdout);
    }

    return 0;
}

实验结果:

查看端口:

附-commen.h

#ifndef COMMEN_H_INCLUDED
#define COMMEN_H_INCLUDED

#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/msg.h>
#include <sys/sem.h>
#include <sys/socket.h>

#include <sys/select.h>

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

#include <arpa/inet.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

#include <iostream>
using namespace std;

void err_exit(std::string str)
{
    perror(str.c_str());
    exit(EXIT_FAILURE);
}
void peerClosePrint(std::string str = "peer connect closed")
{
    cerr << str << endl;
    _exit(0);
}

#endif // COMMEN_H_INCLUDED

附-Makefile

CC = g++
CPPFLAGS = -Wall -g -pthread

BIN = server client
SOURCES = $(BIN.=.cpp)

.PHONY: clean all 

all: $(BIN)

clean:
    -rm -rf $(BIN) bin/ obj/ core

时间: 2024-11-05 16:08:48

Socket编程实践(13) --UDP编程基础(1)的相关文章

Socket编程实践(12) --UDP编程基础

UDP特点 无连接,面向数据报(基于消息,不会粘包)的数据传输服务; 不可靠(可能会丢包, 乱序, 重复), 但因此一般情况下UDP更加高效; UDP客户/服务器模型 UDP-API使用 #include <sys/types.h> #include <sys/socket.h> ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *a

Socket编程实践(14) --UDP编程基础(2)

使用UDP注意事项 1.UDP报文可能会丢失.重复.乱序 2.UDP缺乏流量控制:当缓冲区写满以后,由于UDP没有流量控制机制,因此会覆盖缓冲区. 3.UDP协议数据报文截断:如果接收到的UDP数据报大于缓冲区,报文可能被截断,后面的部分会丢失. 4.使用UDP: recvfrom返回0,不代表连接关闭,因为UDP是无连接的. 而且sendto可以发送数据0包(只含有UDP首部[20字节]); 5.ICMP异步错误 观察现象:关闭UDP服务端,启动客户端,从键盘接受数据后,再发送数据.UDP客户

基于socket的TCP和UDP编程

一.概述 TCP(传输控制协议)和UDP(用户数据报协议是网络体系结构TCP/IP模型中传输层一层中的两个不同的通信协议. TCP:传输控制协议,一种面向连接的协议,给用户进程提供可靠的全双工的字节流,TCP套接口是字节流套接口(STream socket)的一种. UDP:用户数据报协议.UDP是一种无连接协议.UDP套接口是数据报套接口(datagram Socket)的一种. 二.TCP和UDP介绍 1)基本TCP客户—服务器服务器 服务器是指在网络环境下运行相应的应用软件,为网上用户提供

Linux下的socket编程实践(十) 基本UDP编程细节

在我的这两篇博客中,简单介绍并实现了基于UDP(TCP)的windows(UNIX下流程基本一致)下的服务端和客户端的程序,本文继续探讨关于UDP编程的一些细节. http://blog.csdn.net/nk_test/article/details/47733307 http://blog.csdn.net/nk_test/article/details/47756381 下图是一个简单的UDP客户/服务器模型: 我在这里也实现了一个简单的UDP回射服务器/客户端: /**实践: 实现一个基

linux系统socket通信编程实践

简单介绍并实现了基于UDP(TCP)的windows(UNIX下流程基本一致)下的服务端和客户端的程序,本文继续探讨关于UDP编程的一些细节. 下图是一个简单的UDP客户/服务器模型: .imageplus-append-lu-img-txt { overflow: hidden; margin: 10px 0 } .imageplus-append-nova-txt { border: 1px solid #f2f2f2; font-family: Microsoft YaHei; line-

网络编程——基于TCP协议的Socket编程,基于UDP协议的Socket编程

Socket编程 目前较为流行的网络编程模型是客户机/服务器通信模式 客户进程向服务器进程发出要求某种服务的请求,服务器进程响应该请求.如图所示,通常,一个服务器进程会同时为多个客户端进程服务,图中服务器进程B1同时为客户进程A1.A2和B2提供服务. Socket概述 ①   所谓Socket通常也称作“套接字”,用于描述IP地址和端口,是一个通信链的句柄.应用程序通常通过“套接字”向网络发出请求或者应答网络请求. ②   Socket是连接运行在网络上的两个程序间的双向通信的端点. ③  

Socket编程实践(6) --TCP粘包原因与解决

流协议与粘包 粘包的表现 Host A 发送数据给 Host B; 而Host B 接收数据的方式不确定 粘包产生的原因 说明 TCP 字节流,无边界 对等方,一次读操作,不能保证完全把消息读完 UDP 数据报,有边界 对方接受数据包的个数是不确定的 产生粘包问题的原因分析 1.SQ_SNDBUF 套接字本身有缓冲区 (发送缓冲区.接受缓冲区) 2.tcp传送的端 mss大小限制 3.链路层也有MTU大小限制,如果数据包大于>MTU要在IP层进行分片,导致消息分割. 4.tcp的流量控制和拥塞控

Java笔记二十三.网络编程基础与UDP编程

网络编程基础与UDP编程 转载请表明出处:http://blog.csdn.net/u012637501(嵌入式_小J的天空) 一.网络编程基础 1.TCP/IP协议:TCP/IP协议是一个非常实用的网络应用程序通信协议,包括TCP(传输控制协议)和IP地址(计算机唯一标识号). 2.IP地址:IP在互联网中能唯一标识一台计算机,是每一台计算机的唯一标识(身份证),通过这个标识号来指定接收数据的计算机和识别发送数据的计算机,该标识号即为IP地址. (1)Ipv4:指在计算机中IP地址用4个字节(

Socket编程实践(6) --TCPNotes服务器

僵尸进程过程 1)通过忽略SIGCHLD信号,避免僵尸进程 在server端代码中加入 signal(SIGCHLD, SIG_IGN); 2)通过wait/waitpid方法.解决僵尸进程 signal(SIGCHLD,onSignalCatch); void onSignalCatch(int signalNumber) { wait(NULL); } 3) 假设多个客户端同一时候关闭, 问题描写叙述如以下两幅图所看到的: watermark/2/text/aHR0cDovL2Jsb2cuY