概述
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:\n"); 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 3000int 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\n");}//初始化服务器断地址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\n");}while(1){printf("begin recv:\n");recv_num = recvfrom(sock_fd,recv_buf,sizeof(recv_buf),0,(struct sockaddr *)&addr_client,&client_len);if(recv_num < 0){printf("bad\n");perror("again recvfrom");exit(1);} else{recv_buf[recv_num]='\0';printf("recv sucess:%s\n",recv_buf);}printf("begin send:\n");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\n");}}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:\n");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\n",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\n");recv_buf[recv_num]='\0';printf("the receive:%s\n",recv_buf);}close(sock_fd);return 0;
}
参考:
- 基于Socket的UDP和TCP编程介绍
- TCP字节流与UDP数据报
- 网络面试试题