TCP和UDP的异同点知识总结

相同点:TCP和UDP都是传输层的协议

不同点:
1.UDP是面向报文的,发送端发啥,接收端就收啥
TCP是面向流的,肯定能发过去,但是不是一次性都发过去,可能是分批次发的,(就像一车一车拉货),这就需要提前约定怎么就知道一句话发完了,需要自己设定,比如遇到\r\n代表一句话收完了

2.TCP是面向连接的, 必须调用connect,建立连接
UDP是无连接的,, 么有调过connect

3.UDP不可靠,只管发,发了对方收到不收到不管
TCP是可靠的,发了对方能收到,收不到我也知道

但是,可靠性是需要付出成本的,有时候不需要那么可靠,比如视频聊天就可以使用UDP,卡一下也没关系,不影响使用

如何写一个UDP服务器?
1) 创界一个UDP socket (DatagramSocket)

DatagramSocket udpServerSocket=new DatagramSocket(8080);

2)循环
-----------a.等待对方发送UDP报文

udpServerSocket
<think>我们正在讨论SOCK_STREAM(TCPSOCK_DGRAM(UDP)套接字在调用connect函数时的相同。根据之前的知识引用材料,我们可以总结如下:相同:1.函数调用形式相同:两者都使用相同的connect函数,函数原型一致。2.参数类型相同:都需要传入套接字描述符、目标地址结构体以及地址长度。3.设置默认通信目标:无论是SOCK_STREAM还是SOCK_DGRAM,调用connect后,都会将传入的地址设置为后续通信的默认目标地址。4.后续发送数据可以不用指定地址:调用connect之后,都可以使用send()或write()发送数据,而不需要每次使用sendto()(对于UDP)或指定目标地址(对于TCP,因为TCP已经建立连接,所以本来就不需要指定)。5.错误检查:在调用connect时,都会对传入的地址参数进行基本的有效性检查(例如地址族是否正确,地址长度是否合理等)。如果地址参数无效,都会返回错误(例如EINVAL)。6.返回值的含义相同:成功时返回0,失败时返回-1(或SOCKET_ERROR,具体取决于平台),并设置errno(或WSAGetLastError()获取错误码)。注意:虽然UDP的connect不会真正建立连接(无网络交互),但在套接字本地状态上,它记录了这个目标地址,因此从这个角度看,两者都改变了套接字的本地状态(即记录了一个默认目标地址)。引用说明:引用[1][4]说明了SOCK_STREAM是面向连接的,可靠的数据流传输,而SOCK_DGRAM是无连接的,不可靠的数据报传输。但是,在调用connect函数时,两者在形式上是一致的,只是内部行为有差异。因此,我们可以这样总结相同。</think>### SOCK_STREAM SOCK_DGRAM 套接字调用 connect() 的相同 #### 1. **基本调用形式相同** - **函数原型一致**: ```c int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen); ``` - **参数要求相同**: - 都需要传入套接字描述符 `sockfd` - 都需要目标地址结构体 `addr`(如 `struct sockaddr_in`) - 都需要地址长度 `addrlen`[^3][^2] #### 2. **核心功能相同** - **设置默认通信目标**: 两者都会将传入的地址设置为后续数据发送的默认目标地址[^2][^4] ```c // TCPUDP共用此语法 struct sockaddr_in serv_addr = { .sin_family = AF_INET, .sin_port = htons(8080), .sin_addr.s_addr = inet_addr("192.168.1.100") }; connect(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)); ``` #### 3. **后续发送操作相同** - **均可使用 send() 发送数据**: 调用 `connect()` 后,两者都允许使用简化发送函数: ```c // 适用于SOCK_STREAMSOCK_DGRAM send(sockfd, buffer, len, 0); ``` 无需再使用 `sendto()` 指定目标地址[^4] #### 4. **错误检查机制相同** - **地址有效性验证**: 两者都会在调用时检查地址参数的有效性,对无效地址返回相同错误: - `EINVAL`:无效参数(如地址长度错误) - `EAFNOSUPPORT`:地址族不支持[^3] #### 5. **本地状态变更相同** - **修改套接字本地状态**: 调用后两者都会在操作系统内核中修改套接字状态: - 记录目标地址信息 - 更新路由缓存 - 设置套接字为"已关联地址"状态[^4] #### 6. **返回值错误处理** - **成功时均返回 0** - **失败时均返回 -1**(Linux)或 `SOCKET_ERROR`(Windows) - 共用部分错误代码: - `EACCES`:权限不足 - `ENETUNREACH`:网络不可达 - `ETIMEDOUT`:连接超时(UDP仅在后续操作暴露)[^3] > **关键总结**:虽然两者协议本质不同(TCP面向连接 vs UDP无连接),但 `connect()` 的调用接口、参数要求、基本地址绑定功能后续发送接口保持高度一致,体现了套接字API的设计统一性[^2][^4]。 --- ### 相关问题 1. UDP套接字调用 `connect()` 后还能使用 `sendto()` 向其他地址发送数据吗? 2. 为什么TCP套接字在已连接状态下再次调用 `connect()` 会失败? 3. 如何检测UDP套接字 `connect()` 后目标地址的可用性? 4. 调用 `connect()` 后,两种套接字的 `getsockname()` `getpeername()` 行为有何异同
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值