Linux学习之旅(28)---C/S模型(UDP)

Linux学习之旅(27)---套接字编程基础知识讲述了套接字编程的一些基础知识和C/S模型(TCP)。在运输层有两个协议面向连接的TCP和无连接的UDP。在这一张我们将讲述C/S模型如何使用UDP实现。关于UDP的特点可以通过Linux学习之旅(25)-----网络协议来了解。

UDP编程框架

1、UDP编程框架图

在UDP编程的框架模型中,没有connect(),listen()和accept()函数,这是由于UDP协议无连接的特性决定的。

2、函数说明

(1)socket():创建套接字

(2)bind():绑定套接字,这两个函数和TCP中的使用方法是相同的。

(3)recvfrom()和recv():接收数据

#include <sys/types.h>
#include <sys/socket.h>
ssize_t recv(int s,void* buf,size_t len,int flags);
ssize_t recvfrom(int s void* buf,size_t len,int flags,struct sockaddr* from ,socklen_t* fromlen);

参数说明:

s:表示正在监听的套接字的文件描述符。

buf:表示接收数据缓冲区,接收到的数据将放在这个指针所指向的空间中。

len:表示数据缓冲区额度大小,系统根据这个值来确保接收区的安全,防止溢出。

flags:默认为0。

from:传出参数,发送方的端口信息。

fromlen:传入传出参数,表示from参数的长度。

返回值:成功返回数据长度,失败返回-1。当返回值为0时,表示系统此时接收不到数据。

(4)send()和sendto():接收数据

#include <sys/types.h>
#include <sys/socket.h>
ssize_t send(int s,const void* buf,size_t len,int flags);
ssize_t sendto(int s ,const void* buf,size_t len,int flags,const struct sockaddr* to ,socklen_t tolen);

参数说明:

s:正在监听的套接字端口。

buf:发送数据缓冲区,发送的数据放在此指针指向的内存空间中。

len:发送数据缓冲区的大小。

to:目的主机的端口。

tolen:目的主机的端口长度。

返回值:成功返回数据长度,失败返回-1。数据长度可以为0。

程序1、UDP服务器端

服务器功能:将客户端发送的数据中的小写字母转化成大写字符,并返回给发送端。

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

#define PORT 5500
#define BUFSIZE 1024

int main()
{
    //创建一个使用ipv4和默认协议的数据报套接字
    int serSock=socket(AF_INET,SOCK_DGRAM,0);
    struct sockaddr_in serAddr;
    //将端口信息清零
    bzero(&serAddr,sizeof(serAddr));
    serAddr.sin_family=AF_INET;
    //INADDR_ANY的值为0,表示本机的所有端口
    serAddr.sin_addr.s_addr=htonl(INADDR_ANY);
    //设置端口号
    serAddr.sin_port=htons(5500);
    //绑定套接字和端口信息
    bind(serSock,(struct sockaddr *)(&serAddr),sizeof(serAddr));
    char dataBuf[BUFSIZE];
    bzero(dataBuf,BUFSIZE);
    printf("UDP SERVER RECVING.....\n");
    while(1)
    {
        struct sockaddr_in cliAddr;
        bzero(&cliAddr,sizeof(cliAddr));
        socklen_t cliAddrLen=sizeof(cliAddr);
        //接收客户端发送的数据
        ssize_t datalen=recvfrom(serSock,(void *)dataBuf,BUFSIZE,0,(struct sockaddr*)(&cliAddr),&cliAddrLen);
        //打印客户端的IP和端口号
        char cliStrIP[32];
        printf("Client IP:%s",inet_ntop(AF_INET,&(cliAddr.sin_addr.s_addr),cliStrIP,sizeof(cliStrIP)));
        printf("client prot:%d\n",ntohs(cliAddr.sin_port));
        //数据处理
        int i=0;
        while(i<datalen)
        {
            dataBuf[i]=toupper(dataBuf[i]);
            ++i;
        }
        //向客户端发送数据
        sendto(serSock,(void *)dataBuf,datalen,0,(struct sockaddr*)(&cliAddr),sizeof(cliAddr));
    }
    //关闭套接字
    close(serSock);
    return 0;
}

程序2、UDP客户端

客户端功能:向服务器发送给消息并将服务器回送的消息显示出来。

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

#define PORT 5500
#define BUFSIZE 1024

int main(int argc,char* argv[])
{
    if(argc<2)
    {
        printf("CLIENT IPADDRESS\n");
        exit(1);
    }
    //创建一个使用IPV4和默认协议的数据报套接字
    int cliSock=socket(AF_INET,SOCK_DGRAM,0);
    struct sockaddr_in serAddr;
    bzero(&serAddr,sizeof(serAddr));
    serAddr.sin_family=AF_INET;
    inet_pton(AF_INET,argv[1],&(serAddr.sin_addr));
    serAddr.sin_port=htons(PORT);
    while(1)
    {
        char dataBuf[BUFSIZE];
        int serAddrLen=sizeof(serAddr);
        scanf("%s",dataBuf);
        sendto(cliSock,(void*)dataBuf,strlen(dataBuf),0,(struct sockaddr*)(&serAddr),sizeof(serAddr));
        recvfrom(cliSock,(void*)dataBuf,BUFSIZE,0,(struct sockaddr*)(&serAddr),&serAddrLen);
        printf("%s",dataBuf);
    }
    close(cliSock);
    return 0;
}

nc命令

nc时netcat的简写,被誉为网络界的瑞士军刀。因为它短小精悍,功能实用。它的作用有以下几个:

(1)实现任意TCP/UDP端口的监听(服务器)。

(2)端口的扫描,nc可以作为client发起TCP/UDP连接(客户端)。

(3)机器之间传输文件。

(4)机器之间网络测速。

nv -[lpsuvwz]

参数说明:

(1)-l:将nc作为服务器,监听并接收连接。

(2)-p:端口号。

(3)-s:指定发送数据的源IP地址,适用于多网卡机。

(4)-u:使用UDP协议,默认为TCP。

(5)-v:输出交互或出错信息。

(6)-w:超时秒数。

(7)-z:表示0,即扫描时不发送数据。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值