服务端代码:
#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;
}