概述
TCP和UDP是网络体系结构TCP/IP模型中传输层一层中的两个不同的通信协议。
- TCP:传输控制协议,一种面向连接的协议,给用户进程提供可靠的全双工的字节流,TCP套接口是字节流套接口(stream socket)的一种。
- UDP:用户数据报协议。UDP是一种无连接协议。UDP套接口是数据报套接口(datagram socket)的一种。
TCP与UDP简介
基本TCP客户—服务器程序设计基本框架
基本UDP客户—服务器程序设计基本框架
UDP和TCP的对比
- TCP面向连接(三次握手机制),通信前需要先建立连接;UDP面向无连接,通信前不需要建立连接;
- TCP保障可靠传输(按序、无差错、不丢失、不重复、超时重发); UDP不保障可靠传输,使用最大努力交付;
- TCP面向字节流的传输,UDP面向数据报的传输。
TCP优缺点:
-
优点:
1.TCP提供以认可的方式显式地创建和终止连接。
2.TCP保证可靠的、顺序的(数据包以发送的顺序接收)以及不会重复的数据传输。
3.TCP处理流控制。
4.允许数据优先
5.如果数据没有传送到,则TCP套接口返回一个出错状态条件。
6.TCP通过保持连续并将数据块分成更小的分片来处理大数据块。—无需程序员知道 -
缺点: TCP在转移数据时必须创建(并保持)一个连接。这个连接给通信进程增加了开销,让它比UDP速度要慢。
UDP优缺点:
1.UDP不要求保持一个连接
2.UDP没有因接收方认可收到数据包(或者当数据包没有正确抵达而自动重传)而带来的开销。
3.设计UDP的目的是用于短应用和控制消息
4.在一个数据包连接一个数据包的基础上,UDP要求的网络带宽比TDP更小。
TCP/IP应用编程接口(API)
-
TCP服务端:
-
TCP客户端:
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>#define PORT 2345
#define DSET_IP_ADDRESS “192.168.218.141”int main(int argc, char *argv[])
{
int sockfd;
char buffer[1024];
struct sockaddr_in server_addr;sockfd = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); if(sockfd == -1) { perror("socket error"); exit(EXIT_FAILURE); } bzero(&server_addr,sizeof(server_addr)); server_addr.sin_family=AF_INET; server_addr.sin_port=htons(PORT); server_addr.sin_addr.s_addr = inet_addr(DSET_IP_ADDRESS); if(connect(sockfd,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr))==-1) { perror("connect error."); exit(EXIT_FAILURE); } do { printf("Please input char:
");
fgets(buffer,1024,stdin);
write(sockfd,buffer,strlen(buffer));} while (strncmp(buffer, "quit", 4) != 0); close(sockfd); exit(EXIT_SUCCESS);
}
-
UDP服务端:
#include<stdio.h>
include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<unistd.h>
#include<errno.h>
#include<string.h>
#include<stdlib.h>#define SERV_PORT 3000
int main(int argc, char *argv[])
{
int sock_fd; //套接子描述符号
int recv_num;
int send_num;
int client_len;
char recv_buf[20];
struct sockaddr_in addr_serv;
struct sockaddr_in addr_client;//服务器和客户端地址sock_fd = socket(AF_INET,SOCK_DGRAM,0); if(sock_fd < 0){ perror("socket"); exit(1); } else { printf("sock sucessful
");
}//初始化服务器断地址 memset(&addr_serv,0,sizeof(struct sockaddr_in)); addr_serv.sin_family = AF_INET;//协议族 addr_serv.sin_port = htons(SERV_PORT); addr_serv.sin_addr.s_addr = htonl(INADDR_ANY);//任意本地址 client_len = sizeof(struct sockaddr_in); /*绑定套接子*/ if(bind(sock_fd,(struct sockaddr *)&addr_serv,sizeof(struct sockaddr_in))<0 ){ perror("bind"); exit(1); } else{ printf("bind sucess
");
}while(1){ printf("begin recv:
");
recv_num = recvfrom(sock_fd,recv_buf,sizeof(recv_buf),0,(struct sockaddr *)&addr_client,&client_len);
if(recv_num < 0){
printf("bad
");
perror(“again recvfrom”);
exit(1);
} else{
recv_buf[recv_num]=‘’;
printf("recv sucess:%s
",recv_buf);
}
printf("begin send:
");
send_num = sendto(sock_fd,recv_buf,recv_num,0,(struct sockaddr *)&addr_client,client_len);
if(send_num < 0){
perror(“sendto”);
exit(1);
} else{
printf("send sucessful
");
}
}
close(sock_fd);return 0;
}
-
UDP客户端:
#include<stdio.h>
#include<string.h>
#include<errno.h>
#include<stdlib.h>
#include<unistd.h>#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>#define DEST_PORT 3000
#define DSET_IP_ADDRESS “192.168.1.103”int main(int argc, char *argv[])
{
int sock_fd;/套接字文件描述符/
int send_num;
int recv_num;
int dest_len;
char send_buf[20]={“hello tiger”};
char recv_buf[20];
struct sockaddr_in addr_serv;/服务端地址,客户端地址/sock_fd = socket(AF_INET,SOCK_DGRAM,0);//创建套接子 //初始化服务器端地址 memset(&addr_serv,0,sizeof(addr_serv)); addr_serv.sin_family = AF_INET; addr_serv.sin_addr.s_addr = inet_addr(DSET_IP_ADDRESS); addr_serv.sin_port = htons(DEST_PORT); dest_len = sizeof(struct sockaddr_in); printf("begin send:
");
send_num = sendto(sock_fd,send_buf,sizeof(send_buf),0,(struct sockaddr *)&addr_serv,dest_len);
if(send_num < 0){
perror(“sendto”);
exit(1);
} else{
printf("send sucessful:%s
",send_buf);
}recv_num = recvfrom(sock_fd,recv_buf,sizeof(recv_buf),0,(struct sockaddr *)&addr_serv,&dest_len); if(recv_num <0 ){ perror("recv_from"); exit(1); } else{ printf("recv sucessful
");
recv_buf[recv_num]=‘’;
printf("the receive:%s
",recv_buf);
}close(sock_fd); return 0;
}
参考: