UDP connect函数并不会引起和目标端的网络交互,也就是说并不会发送所谓的“握手”报文的发送和应答
UDP connect的主要作用就是让客户端套接字和目标程序绑定,当发送目标有错误返回时(例如icmp报文),让错误报文等够被正确的套接字接收,而不是丢弃掉
例如下面的客户端程序启动而不启动服务端,绑定的话,如果对端不可达会返回错误信息并被recvfrom接收,而不会到时在recvfrom哪里阻塞。
#include <stdio.h>
#include <stdlib.h>
#include "lib/common.h"
#define MAXLINE 4096
int main() {
int sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(1234);
inet_pton(AF_INET, "127.0.0.1", &server_addr.sin_addr);
int server_len = sizeof(server_addr);
if (connect(sock_fd, (struct sockaddr*)&server_addr, server_len)) {
error(1, errno, "connect failed!!");
}
char buf[MAXLINE];
struct sockaddr_in replay;
int replay_len = sizeof(replay);
while (scanf("%s", buf) != EOF) {
int rt = sendto(sock_fd, buf, strlen(buf), 0, (struct sockaddr*)&server_addr, sizeof(server_addr));
if (rt < 0) {
error(1, errno, "sendto failed");
}
printf("sended\n");
fflush(stdout);
buf[0] = 0;
rt = recvfrom(sock_fd, buf, MAXLINE, 0, (struct sockaddr*)&replay, &replay_len);
if (rt < 0) {
error(1, errno, "recvfrom failed");
}
buf[rt] = 0;
printf("recv: %s rt: %d\n", buf, rt);
}
}
服务端也可以使用connect绑定客户端地址,不过这样做的话服务器就不能相应其他的客户端发来的消息。
注意使用connect之后 udp接收发送函数可以使用send/write recv发送接收消息 如果强行使用recvfrom等函数的话,系统内核也会将from和to参数忽略
以下是服务端程序示例
#include <stdio.h>
#include <stdlib.h>
#include "lib/common.h"
#define MAXLINE 1024
int main() {
int sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
struct sockaddr_in server_addr, client_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(1234);
inet_pton(AF_INET, "127.0.0.1", &server_addr.sin_addr);
int server_len = sizeof(server_addr);
bind(sock_fd, (struct sockaddr*)&server_addr, sizeof(server_addr));
char buf[MAXLINE];
int client_len = sizeof(client_addr);
int rt = recvfrom(sock_fd, buf, MAXLINE, 0, (struct sockaddr*)&client_addr, &client_len);
if (rt < 0) {
error(1, errno, "recvfrom is failed");
}
printf("recive: %s\n", buf);
if (connect(sock_fd, (struct sockaddr*)&client_addr, sizeof(client_addr))) {
error(1, errno, "connect failed!!");
}
while (1) {
strcpy(buf, "recived");
rt = send(sock_fd, buf, strlen(buf), 0);
if (rt < 0) {
error(1, errno, "send is failed");
}
rt = recv(sock_fd, buf, MAXLINE, 0);
if (rt < 0) {
error(1, errno, "recv is failed");
}
printf("buf: %s\n", buf);
}
}