两个线程共享一个套接字,其中一个线程使用sendmsg函数不断发送消息到该套接字,另一个线程使用recvmsg函数不断接收该套接字的消息,并打印出来的功能
以下是使用C语言写的一段代码,实现两个线程共享一个套接字,其中一个线程使用sendmsg函数不断发送消息到该套接字,另一个线程使用recvmsg函数不断接收该套接字的消息,并打印出来的功能
点击查看代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
int sockfd;
void *send_func(void *arg)
{
while(1)
{
// 获取要发送的消息
char msg[1024];
printf("请输入要发送的消息:\n");
if(fgets(msg, 1024, stdin) == NULL)
{
printf("fgets error!\n");
exit(1);
}
// 构造发送消息
struct sockaddr_in server_addr;
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(8000);
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
struct msghdr message;
struct iovec iov[1];
char ctrl[sizeof(struct cmsghdr) + sizeof(int)];
memset(&message, 0, sizeof(struct msghdr));
memset(ctrl, 0, sizeof(ctrl));
iov[0].iov_base = msg;
iov[0].iov_len = strlen(msg);
message.msg_name = &server_addr;
message.msg_namelen = sizeof(server_addr);
message.msg_iov = iov;
message.msg_iovlen = 1;
message.msg_control = ctrl;
message.msg_controllen = sizeof(ctrl);
size_t len = strnlen(msg, 1024) + 1;
struct cmsghdr *p;
p = CMSG_FIRSTHDR(&message);
p->cmsg_len = sizeof(ctrl);
p->cmsg_level = SOL_SOCKET;
p->cmsg_type = SCM_RIGHTS;
*(int *)CMSG_DATA(p) = sockfd;
if(sendmsg(sockfd, &message, 0) == -1)
{
perror("sendmsg error!");
exit(1);
}
sleep(1); // 模拟不断发送消息
}
}
void *recv_func(void *arg)
{
while(1)
{
// 构造接收消息
struct sockaddr_in client_addr;
socklen_t addrlen = sizeof(client_addr);
struct msghdr message;
struct iovec iov[1];
char ctrl[sizeof(struct cmsghdr) + sizeof(int)];
memset(&message, 0, sizeof(struct msghdr));
memset(ctrl, 0, sizeof(ctrl));
iov[0].iov_base = malloc(1024);
iov[0].iov_len = 1024;
message.msg_name = &client_addr;
message.msg_namelen = addrlen;
message.msg_iov = iov;
message.msg_iovlen = 1;
message.msg_control = ctrl;
message.msg_controllen = sizeof(ctrl);
struct cmsghdr *p;
p = CMSG_FIRSTHDR(&message);
p->cmsg_len = sizeof(ctrl);
p->cmsg_level = SOL_SOCKET;
p->cmsg_type = SCM_RIGHTS;
*(int *)CMSG_DATA(p) = sockfd;
if(recvmsg(sockfd, &message, 0) == -1)
{
perror("recvmsg error!");
free(iov[0].iov_base);
exit(1);
}
// 输出接收到的消息
char recvmsg[1024];
strncpy(recvmsg, iov[0].iov_base, iov[0].iov_len);
recvmsg[iov[0].iov_len] = '\0';
printf("收到消息:%s", recvmsg);
free(iov[0].iov_base);
}
}
int main(int argc, char *argv[])
{
// 创建套接字
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if(sockfd == -1)
{
perror("socket error!");
return 0;
}
// 绑定套接字
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(8000);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
if(bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)) == -1)
{
perror("bind error!");
return 0;
}
// 创建两个线程,一个发送消息,一个接收消息
pthread_t send_tid, recv_tid;
if(pthread_create(&send_tid, NULL, send_func, NULL) != 0)
{
perror("pthread_create error!");
return 0;
}
if(pthread_create(&recv_tid, NULL, recv_func, NULL) != 0)
{
perror("pthread_create error!");
return 0;
}
// 等待线程结束
if(pthread_join(send_tid, NULL) != 0)
{
perror("pthread_join error!");
return 0;
}
if(pthread_join(recv_tid, NULL) != 0)
{
perror("pthread_join error!");
return 0;
}
// 关闭套接字
close(sockfd);
return 0;
}
本文来自博客园,作者:开源侠,转载请注明原文链接:https://www.cnblogs.com/cyj22/p/17902887.html
微信公众号:青衫换酒吃