1. 程式人生 > >資料報服務與流式服務的區別

資料報服務與流式服務的區別

一、UDP資料報服務與TCP流式服務的示圖分析

這裡寫圖片描述

1、位元組流服務:傳送端send()只是將資料寫到TCP傳送緩衝區中,然後將傳送緩衝區中的資料打包成報文段傳送出去。接收端又將接收到的報文段寫到緩衝區中,最後recv()直接取資料。

位元組流服務特點:資料沒有明確分割(由底層做分割),不分一定的報文段,什麼時候想發便可將寫入緩衝區的資料,進行打包再發送,即send()與recv()的次數沒有必然聯絡。

2、資料報服務:傳送端sendto()將資料直接打包成相對應的報文段傳送。
資料報服務特點:資料有明確分割,拿資料按報文段拿。

3、程式碼示例:

TCP協議
TCP協議服務端:

#include <stdio.h>
#include <stdlib.h> #include <assert.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <sys/types.h> #include <arpa/inet.h> #include <netinet/in.h> void main() { //建立socket int sock=socket(PF_INET,SOCK_STREAM,0);//第一個引數告訴系統使用哪個底層協議族,對於tcp協議來說,一般設定為PF—INET表示IPv4,PF—INET6表示IPv6;第二個引數表示服務型別為流服務,第三個引數表示預設協議,一般為0;
assert(sock!=-1); struct sockaddr_in ser,cli;//ser服務端,cli客-戶端 memset(&ser,0,sizeof(&ser)); ser.sin_family= AF_INET;//地址族 ser.sin_port=htons(6500);//埠號(使用者向網路,以short型別) ser.sin_addr.s_addr=inet_addr("127.0.0.1");//IP地址 //繫結socket int res=bind(sock,(struct sockaddr*)&ser,sizeof
(ser)); assert(res!=-1); //監聽socket listen(sock,5); while(1) { int len=sizeof(cli); //接受連線 int c=accept(sock,(struct sockaddr*)&cli,&len); assert(c!=-1); printf("one client link\n"); //接收資料 while(1) { char buff[128]={0}; int n=recv(c,buff,2,0); if(n<=0) { printf("client link break\n"); break; } printf("buff:%s,n=%d\n",buff,n); //傳送資料 send(c,"OK",2,0);//第二個和第三個引數分別指寫緩衝區位置和大小 } close(c); } //關閉 close(sock); }

TCP協議客戶端:

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netinet/in.h>
void main()
{
    //建立socket
    int sock=socket(PF_INET,SOCK_STREAM,0);
    assert(sock!=-1);
    struct sockaddr_in ser,cli;//ser服務端,cli客戶端
    ser.sin_family = AF_INET;//地址族
    ser.sin_port=htons(6500);//埠號(使用者向網路,以short型別)
    ser.sin_addr.s_addr=inet_addr("127.0.0.1");//IP地址
    //發起socket
    int res= connect(sock,(struct sockaddr*)&ser,sizeof(ser));//第二個引數指定連結的是伺服器上哪個程序
    assert(res!=-1);
    while(1)
    {
        printf("please input: "),fflush(stdout);
        char buff[128]={0};
        fgets(buff,128,stdin);
        buff[strlen(buff)-1]=0;
        if(strncmp(buff,"end",3)==0)
        {
            break;
        }
    send(sock,buff,strlen(buff),0);
    memset(buff,0,128);
    recv(sock,buff,2,0); 
    printf("%s\n",buff);
    }
    close(sock);
}

UDP協議
UDP協議服務端:

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netinet/in.h>
void main()
{
    int sock=socket(PF_INET,SOCK_DGRAM,0);
    assert(sock!=-1);
    struct sockaddr_in ser,cli;//ser服務端,cli客戶端
    memset(&ser,0,sizeof(&ser));
    ser.sin_family= AF_INET;//地址族
    ser.sin_port=htons(6500);//埠號(使用者向網路,以short型別)
    ser.sin_addr.s_addr=inet_addr("192.168.1.129");//IP地址
    //繫結socket
    int res=bind(sock,(struct sockaddr*)&ser,sizeof(ser));
    assert(res!=-1);
    while(1)
    {
        char buff[128]={0};
        int len=sizeof(cli);
        recvfrom(sock,buff,2,0,(struct sockaddr*)&cli,&len);
        printf("srcaddr:%s,port:%d\n",inet_ntoa(cli.sin_addr),
                ntohs(cli.sin_port));
        printf("buff:%s\n",buff);
        sendto(sock,"OK",2,0,(struct sockaddr*)&cli,len);
    }
    close(sock);
}

UDP協議客戶端:

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netinet/in.h>
void main()
{
    int sock=socket(PF_INET,SOCK_DGRAM,0);
    assert(sock!=-1);
    struct sockaddr_in ser,cli;//ser服務端,cli客戶端
    memset(&ser,0,sizeof(&ser));
    ser.sin_family= AF_INET;//地址族
    ser.sin_port=htons(6500);//埠號(使用者向網路,以short型別)
    ser.sin_addr.s_addr=inet_addr("192.168.1.129");//IP地址
    while(1)
    {
        printf("please input: "),fflush(stdout);
        char buff[128]={0};
        fgets(buff,128,stdin);
        buff[strlen(buff)-1]=0;
        int len=sizeof(cli);
        sendto(sock,"OK",strlen(buff),0,(struct sockaddr*)&ser,sizeof(ser));
        memset(buff,0,128);
        recvfrom(sock,buff,2,0,NULL,NULL);
        printf("%s\n",buff);
    }
    close(sock);
}