SO_REUSEPORT 网络编程用例

服务端代码:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <netdb.h>

void create_children(int nprocs, int parent_pid)
{
	while (nprocs-- > 0) {
		if (getpid() == parent_pid && fork() < 0)
			exit(1);
	}
}

int main(int argc, char *argv[])
{
	int reuse_port, fd, cfd, nprocs, opt = 1, parent_pid = getpid();
	struct sockaddr_in server;
	
	if (argc != 4) {
		fprintf(stderr, "Port# #Procs {0->fork, or 1->SO_REUSEPORT}\n");
		return 1;
	}

	nprocs = atoi(argv[2]);
	reuse_port = atoi(argv[3]);
	
	if (reuse_port) /* proper SO_REUSEPORT */
		create_children(nprocs, parent_pid);
	
	if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
		perror("socket");
		return 1;
	}

	if (reuse_port)
		setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, (char *)&opt, sizeof opt);
	
	server.sin_family = AF_INET;
	server.sin_addr.s_addr = INADDR_ANY;
	server.sin_port = htons(atoi(argv[1]));
	
	if (bind(fd, (struct sockaddr *)&server, sizeof server) < 0) {
		perror("bind");
		return 1;
	}
	
	if (!reuse_port) /* simple fork instead of SO_REUSEPORT */
		create_children(nprocs, parent_pid);
		
	if (parent_pid == getpid()) {
		while (wait(NULL) != -1); /* wait for all children */
	} else {
		listen(fd, SOMAXCONN);
		while (1) {
			if ((cfd = accept(fd, NULL, NULL)) < 0) {
				perror("accept");
				return 1;
			}
		close(cfd);
		}
	}
	
	return 0;
}

客户端代码:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <strings.h>
#include <sys/wait.h>
#include <netdb.h>

void create_children(int nprocs, int parent_pid)
{
	while (nprocs-- > 0) {
		if (getpid() == parent_pid && fork() < 0)
			exit(1);
	}
}

int main(int argc, char *argv[])
{
	int fd, count, nprocs, parent_pid = getpid();
	struct sockaddr_in server;
	struct hostent *server_ent;
	const struct linger nolinger = { .l_onoff = 1, .l_linger = 0 };
	
	if (argc != 5) {
		fprintf(stderr, "Server-IP Port# #Processes #Conns_per_Proc\n");
		return 1;
	}
	
	nprocs = atoi(argv[3]);
	count = atoi(argv[4]);
	
	if ((server_ent = gethostbyname(argv[1])) == NULL) {
		perror("gethostbyname");
		return 1;
	}
	
	bzero((char *)&server, sizeof server);
	server.sin_family = AF_INET;
	server.sin_port = htons(atoi(argv[2]));
	bcopy((char *)server_ent->h_addr, (char *)&server.sin_addr.s_addr, server_ent->h_length);
	
	create_children(nprocs, parent_pid);
	
	if (getpid() == parent_pid) {
		/* Parent does nothing other than wait for children */
		while (wait(NULL) != -1);
	} else {
		/* while the children connect() ‘count’ times to the server */
		while (count-- > 0) {
			if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
				perror("socket");
				return 1;
			}
			
			if (connect(fd, (struct sockaddr *)&server, sizeof server) < 0) {
				perror("connect");
				return 1;
			}
			
			/* Reset connection to avoid TIME-WAIT state */
			setsockopt(fd, SOL_SOCKET, SO_LINGER, &nolinger, sizeof nolinger);
			close(fd);
		}
	}
	
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值