資料報服務與流式服務的區別
阿新 • • 發佈:2019-02-08
一、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);
}