TCP 与 UDP实例

Posted Heavy sea

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了TCP 与 UDP实例相关的知识,希望对你有一定的参考价值。

有关TCP和UDP参照之前的博文

相关API和解释都可以参照之前的博文,这里只是采用send/recv函数实现TCP编程,同时实现了UDP编程

一、相关API

1.send函数

ssize_t send(int sockfd, const void *buf, size_t len, int flags);

  • sockfd 指定发送端套接字描述符;
  • buf 指明一个存放应用程序要发送数据的缓冲区;
  • len 指明实际要发送的数据的字节数;
  • flags 一般置0。
  • 客户或者服务器应用程序都用send函数来向TCP连接的另一端发送数据

2.recv函数

ssize_t recv(int sockfd, void *buf, size_t len, int flags);

  • sockfd 指定接收端套接字描述符;
  • buf 指明一个缓冲区,该缓冲区用来存放recv函数接收到的数据;
  • len 指明buf的长度;
  • flags 一般置0。
  • 客户或者服务器应用程序都用recv函数从TCP连接的另一端接收数据。

3.recvfrom函数

ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
struct sockaddr *src_addr, socklen_t *addrlen);

  • recvfrom通常用于无连接套接字,因为此函数可以获得发送者的地址。
  • src_addr 是一个struct sockaddr类型的变量,该变量保存源机的IP地址及端口号。
  • addrlen 常置为sizeof (struct sockaddr)。

4.sendto函数

ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
const struct sockaddr *dest_addr, socklen_t addrlen);

  • sendto和send相似,区别在于sendto允许在无连接的套接字上指定一个目标地址。
  • dest_addr 表示目地机的IP地址和端口号信息,
  • addrlen 常常被赋值为sizeof (struct sockaddr)。
  • sendto 函数也返回实际发送的数据字节长度或在出现发送错误时返回-1。

二、TCP实例

tcpServer

#include <stdio.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>

#define SERVER_PORT 8888
#define BACKLOG 10

/*
*scocket服务端
*
*1.socket
*2.bind
*3.listen
*4.accept
*5.send/recv
*/
int main(int argc,char **argv)
{   
    int socketServer;
    int socketClient;
    int addrlen;
    int Ret;
    int recvLen;
    int clientNum = 0;
    char RcvBuf[1024];
    struct sockaddr_in socketServer_addr;
    struct sockaddr_in socketClient_addr;
    
    socketServer = socket(AF_INET , SOCK_STREAM , 0);
    if(-1==socketServer)
    {
        printf("socket err\\n");
        return -1;
    }

    socketServer_addr.sin_family = AF_INET;
    socketServer_addr.sin_port = htons(SERVER_PORT);  /* host to net, short */
    socketServer_addr.sin_addr.s_addr = INADDR_ANY;
    memset(socketServer_addr.sin_zero,0,8);
    
    Ret = bind(socketServer, (struct sockaddr*)&socketServer_addr, sizeof(struct sockaddr));
    if(-1==Ret)
    {
        printf("bind err\\n");
        return -1;
    }    

    
    Ret = listen(socketServer, BACKLOG);
    if(-1==Ret)
    {
        printf("listen err\\n");
        return -1;
    } 

    while(1)
    {
        
        addrlen = sizeof(socketClient_addr);
        socketClient = accept(socketServer, (struct sockaddr*)&socketClient_addr,&addrlen);
        if(-1 != socketClient)
        {   
            clientNum++;
            printf("get %d connect %s from client\\n",clientNum,inet_ntoa(socketClient_addr.sin_addr));
            if(!fork())
            {
                while(1)
                {    
                    memset(RcvBuf,0,sizeof(RcvBuf));
                    recvLen = recv(socketClient, RcvBuf, 1000, 0);
                    if(recvLen<=0)
                    {
                        close(socketClient);
                        return -1;
                    }else{
                        printf("get buf:from %d:%s\\n",clientNum,RcvBuf);
                    }
                }
            }
        }

    }

    close(socketServer);
    
    return 0;
}

tcpClient

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

#define SERVER_PORT 8888
#define BACKLOG 10

/*
*scocket客户端
*
*1.socket
*2.connect
*3.send/recv
*/
int main(int argc,char **argv)
{   
    int socketClient;
    int Ret;
    int sendLen;
    char SendBuf[1024];
    struct sockaddr_in socketServer_addr;

    if(argc!=2)
    {
        printf("Usage:");
        printf("%s <serverIp>\\n",argv[0]);
        return -1;
    }
    
    socketClient = socket(AF_INET , SOCK_STREAM , 0);
    if(-1==socketClient)
    {
        printf("socket err\\n");
        return -1;
    }

    socketServer_addr.sin_family = AF_INET;
    socketServer_addr.sin_port = htons(SERVER_PORT);  /* host to net, short */
    inet_aton(argv[1],&socketServer_addr.sin_addr);
    memset(socketServer_addr.sin_zero,0,8);

    Ret = connect(socketClient, (struct sockaddr*)&socketServer_addr,sizeof(struct sockaddr));
    if(-1 == Ret)
    {
        printf("connect err\\n");
        return -1;
    }
    
   while(1)
    {
        memset(SendBuf,0,sizeof(SendBuf));
        if(fgets(SendBuf,1000,stdin))
        {
            sendLen = send(socketClient, SendBuf, strlen(SendBuf), 0);
            if(sendLen<=0)
            {
                close(socketClient);
                return -1;
            }
        }
        
    }
  
    return 0;
}

三、UDP实例

udpServer

#include <stdio.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>

#define SERVER_PORT 8888
#define BACKLOG 10

/*UDP
*scocket服务端
*
*1.socket
*2.bind
*3.recvfrom
*/
int main(int argc,char **argv)
{   
    int socketServer;
    int socketClient;
    int addrlen;
    int Ret;
    int recvLen;
    int clientNum = 0;
    char RcvBuf[1024];
    struct sockaddr_in socketServer_addr;
    struct sockaddr_in socketClient_addr;
    
    socketServer = socket(AF_INET , SOCK_STREAM , 0);
    if(-1==socketServer)
    {
        printf("socket err\\n");
        return -1;
    }

    socketServer_addr.sin_family = AF_INET;
    socketServer_addr.sin_port = htons(SERVER_PORT);  /* host to net, short */
    socketServer_addr.sin_addr.s_addr = INADDR_ANY;
    memset(socketServer_addr.sin_zero,0,8);
    
    Ret = bind(socketServer, (struct sockaddr*)&socketServer_addr, sizeof(struct sockaddr));
    if(-1==Ret)
    {
        printf("bind err\\n");
        return -1;
    }    


    while(1)
    {
        addrlen = sizeof(struct sockaddr);
        recvLen = recvfrom(socketServer, RcvBuf, 1000, 0,
                        (struct sockaddr*)&socketClient_addr, &addrlen);
        
        printf("Get Msg From %s : %s\\n", inet_ntoa(socketClient_addr.sin_addr), RcvBuf);
    }

    close(socketServer);
    
    return 0;
}

udpClient

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

#define SERVER_PORT 8888
#define BACKLOG 10

/*UDP
*scocket客户端
*
*1.socket
*2.connect
*3.send/recv
*/
int main(int argc,char **argv)
{   
    int socketClient;
    int Ret;
    int addrlen;
    int sendLen;
    char SendBuf[1024];
    struct sockaddr_in socketServer_addr;

    if(argc!=2)
    {
        printf("Usage:");
        printf("%s <serverIp>\\n",argv[0]);
        return -1;
    }
    
    socketClient = socket(AF_INET , SOCK_DGRAM , 0);
    if(-1==socketClient)
    {
        printf("socket err\\n");
        return -1;
    }

    socketServer_addr.sin_family = AF_INET;
    socketServer_addr.sin_port = htons(SERVER_PORT);  /* host to net, short */
    inet_aton(argv[1],&socketServer_addr.sin_addr);
    memset(socketServer_addr.sin_zero,0,8);

/*    Ret = connect(socketClient, (struct sockaddr*)&socketServer_addr,sizeof(struct sockaddr));
    if(-1 == Ret)
    {
        printf("connect err\\n");
        return -1;
    } */
    
   while(1)
    {
        memset(SendBuf,0,sizeof(SendBuf));
        if(fgets(SendBuf,1000,stdin))
        {   
            addrlen = sizeof(struct sockaddr);
            sendLen = sendto(socketClient, SendBuf, strlen(SendBuf), 0,(struct sockaddr*)&socketServer_addr, addrlen);
            if(sendLen<=0)
            {
                close(socketClient);
                return -1;
            }
        }
        
    }
  
    return 0;
}

以上是关于TCP 与 UDP实例的主要内容,如果未能解决你的问题,请参考以下文章

TCP 与 UDP实例

MicroPython ESP32 UDP和TCP数据收发通讯综合实例

Python 之 Socket编程(TCP/UDP)

SCTP协议详解与实例

NodeJS编写简单TCP/UDP端口代理转发服务

4 TCP与UDP与WebSocket