TCP/UDP通信解疑
一、TCP是面向流的通信,这个什么意思呢,你read一下,可能从流的任何一点拿数据;然后呢,你需要对应用层的数据做封包处理。
封包可以使用数据类型和数据长度,或者使用某些字符串隔离包,可能是\n,说到这里,为何http请求没有指明数据长度呢,以前http通信是短连接只有一问一答,因此不需要数据长度;
后来http1.1出现keep-alive的长连接,但是它有诸如content-length等的报文头,而且http具有明确的开始点。
二、UDP是面向数据报的通信,它的使用简单,但有其最大报文不能超过64k,否则send失败;包之间具有明确界限,每次recv都会读取一个包,假设应用给
的buffer不够它本身的长度,其余部分也被抛弃。
以下是linux gcc 4.84的验证:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <pthread.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <errno.h> void client_p() { sleep(1);//can use semphore struct sockaddr_in addr; int sock; if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { perror("client socket error"); return NULL; } addr.sin_family = AF_INET; addr.sin_port = htons(8765); addr.sin_addr.s_addr = inet_addr("127.0.0.1"); char buff[10]; int n = 0; int len = sizeof(addr); do { n = sendto(sock, "123456789", 10, 0, (struct sockaddr*)&addr, sizeof(sockaddr)); if (n < 0) { perror("sendto server 1 error"); break; } n = recvfrom(sock, buff, 10, 0, (struct sockaddr*)&addr, &len); //if n = sendto(sock, "987654321", 10, 0, (struct sockaddr*)&addr, sizeof(sockaddr)); //if } while (0); close(sock); return NULL; } void server_p() { struct sockaddr_in addr; int sock; if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { perror("server socket error"); return NULL; } addr.sin_family = AF_INET; addr.sin_port = htons(8765); addr.sin_addr.s_addr = inet_addr("127.0.0.1"); char buff[10]; int n = 0; int len = sizeof(addr); do { if (bind(sock, (struct sockaddr*)&addr, len) < 0) { perror("bind error"); break; } n = recvfrom(sock, buff, 4, 0, (struct sockaddr*)&addr, &len); if (n < 0) { perror("recvfrom client 1 error"); break; } else { printf("recv 1:%s\n", buff);//buff is a string } n = sendto(sock, "1", 1, 0, (struct sockaddr*)&addr, sizeof(sockaddr)); //if (n < 0) n = recvfrom(sock, buff, 4, 0, (struct sockaddr*)&addr, &len); if (n < 0) { perror("recvfrom client 2 error"); break; } else { printf("recv 2:%s\n", buff);//buff is a string } } while (0); close(sock); return NULL; } int main(int argc, char**argv) { int ret = 0; pthread_t client, server; ret = pthread_create(&server, NULL, (void*)server_p, NULL); //if ret = pthread_create(&client, NULL, (void*)client_p, NULL); //if pthread_join(server); pthread_join(client); return 0; }
输出结果是:
1234
9876