一、数据报socket编程
服务端:
struct sockaddr_in svaddr,claddr;
int sockfd;
char buf[256];
sockfd = socket(AF_INET, SOCK_DGRAM,0);//创建socket
memset(&svaddr, 0x00, sizeof(struct sockaddr_in));//填写服务端地址
svaddr.sin_family = AF_INET;
svaddr.sin_addr.s_addr = htonl(INADDR_ANY);
svaddr.sin_port = htons(50000);
bind(sockfd,(struct sockaddr*)&svaddr, sizeof(svaddr));//绑定sockfd和服务端地址
int len = sizeof(struct sockaddr_in);
recvfrom(sockfd, buf,BUF_SIZE, 0, (struct sockaddr*)&claddr, &len);//注意这里的地址是客户端的地址,可以理解,是从客户端接受的,会返回客户端地址信息在claddr结构中
客户端:
struct sockaddr_in svaddr;
char str[] = "helloworld";
char ipstring[256] = "127.0.0.1";
int sockfd = socket(AF_INET, SOCK_DGRAM,0);//创建socket
memset(&svaddr ,0, sizeof(struct sockaddr_in));//依然填写服务端地址
svaddr.sin_family = AF_INET;
svaddr.sin_port = htons(50000);
inet_pton(AF_INET, ipstring,&svaddr.sin_addr);
int len = sizeof(struct sockaddr_in);
sendto(sockfd, str,sizeof(str),0,(struct sockaddr*)&svaddr,len);//接受,从服务端,注意最后一个参数是len
inet_pton函数中,ipstring参数,必须是数组形式即char ipstring[],如果定义char *ipstring并传入ipstring会出现段错误。
二、使用msg来传递消息
服务端:
struct sockaddr_in svaddr;
int sockfd;
struct sockaddr_in *claddr;
char buf[256];
sockfd = socket(AF_INET, SOCK_DGRAM,0);
memset(&svaddr, 0x00, sizeof(struct sockaddr_in));
svaddr.sin_family = AF_INET;
svaddr.sin_addr.s_addr = htonl(INADDR_ANY);
svaddr.sin_port = htons(50000);
bind(sockfd,(struct sockaddr*)&svaddr, sizeof(svaddr));//到这里为止,都是一般的socket创建方法
struct msghdr msg;
claddr = malloc(sizeof(struct sockaddr_in));//开始填写msghdr结构
msg.msg_name = claddr;//将客户端地址填入
msg.msg_namelen = sizeof(struct sockaddr_in);
struct iovec iov;
iov.iov_base = buf;
iov.iov_len = sizeof(buf);
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
size_t len = recvmsg(sockfd, &msg,0);//msg中会返回客户端的地址,与recvfrom相似。
claddr = msg.msg_name;
char *temp = msg.msg_iov[0].iov_base;
close(sockfd);
客户端:
nt main()
{
struct sockaddr_in svaddr;
struct msghdr msg;
struct iovec iov;
char str[] = "helloworld";
char ipstring[256] = "127.0.0.1";
memset(&msg,0,sizeof(struct msghdr));
iov.iov_base = str;//将希望发送的数据填好
iov.iov_len = sizeof(str);
int sockfd = socket(AF_INET, SOCK_DGRAM,0);//同样的创建好服务端的socket地址
memset(&svaddr ,0, sizeof(struct sockaddr_in));
svaddr.sin_family = AF_INET;
svaddr.sin_port = htons(50000);
inet_pton(AF_INET, ipstring,&svaddr.sin_addr);
msg.msg_name = &svaddr;//将服务端地址填入
msg.msg_namelen = sizeof(struct sockaddr_in);
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
ssize_t size = sendmsg(sockfd, &msg, 0);
close(sockfd);
}
对比两者,服务端和客户端都要创建并填写好svaddr。sendto sendmsg,recvfrom recvmsg中地址参数是对方地址;并且recvfrom recvmsg都可以返回客户端地址信息。