Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <cstdio>
- #include <cstdlib>
- #include <unistd.h>
- #include <errno.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <netdb.h>
- #include <arpa/inet.h>
- int create_socket(bool server = false)
- {
- addrinfo hints = {};
- addrinfo* servinfo;
- int sockfd = -1;
- int rv;
- hints.ai_family = AF_INET;
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_flags = server ? AI_PASSIVE : 0;
- if ((rv = getaddrinfo(server ? 0 : "localhost", "12345", &hints, &servinfo)))
- {
- printf("getaddrinfo failed: %s\n", gai_strerror(rv));
- exit(1);
- }
- for(auto p = servinfo; p; p = p->ai_next)
- {
- if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1)
- {
- perror("socket");
- continue;
- }
- if(server)
- {
- int yes = 1;
- setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));
- if(bind(sockfd, p->ai_addr, p->ai_addrlen) == -1)
- {
- close(sockfd);
- perror("bind");
- continue;
- }
- }
- else
- {
- if(connect(sockfd, p->ai_addr, p->ai_addrlen) == -1)
- {
- close(sockfd);
- perror("connect");
- continue;
- }
- else
- puts("client: connected");
- }
- break;
- }
- freeaddrinfo(servinfo);
- return sockfd;
- }
- void server()
- {
- int socket = create_socket(true);
- if(listen(socket, 5) == -1)
- {
- perror("listen");
- exit(1);
- }
- puts("server: listening");
- int conn = -1;
- sockaddr_storage addr;
- unsigned int sizeof_addr = sizeof(addr);
- for(;;)
- {
- if((conn = accept(socket, (sockaddr *) &addr, &sizeof_addr)) == -1)
- {
- perror("accept");
- }
- else
- {
- puts("server: accept");
- if(!fork()) // actually not necessary, only got 1 client
- {
- close(socket);
- char *buf = new char[1024*1024];
- for(;;) read(conn, buf, 1024*1024); // black hole
- }
- }
- }
- }
- void do_send(int socket, const char* buf, unsigned int size/*, bool nonblock = false */)
- {
- unsigned int sent = 0;
- unsigned int count = 0;
- while(sent < size)
- {
- // int n = send(socket, &buf[sent], size - sent, nonblock ? MSG_DONTWAIT : 0);
- int n = send(socket, &buf[sent], size - sent, 0);
- if (n == -1)
- {
- if(errno == EAGAIN)
- {
- printf(".");
- }
- else
- {
- perror("\nsend");
- return;
- }
- }
- else
- {
- sent += n;
- printf(" --> sent a chunk of %u bytes (send no. %u, total sent = %u)\n", n, ++count, sent);
- }
- }
- }
- void client()
- {
- const unsigned int max_size = 64*1024*1024; // sending up to 64MiB in one call
- sleep(1); // give server a second to start up
- int socket = create_socket();
- unsigned int send_buffer_size = 0;
- unsigned int len = sizeof(send_buffer_size);
- if(getsockopt(socket, SOL_SOCKET, SO_SNDBUF, &send_buffer_size, &len))
- perror("getsockopt");
- // Linux internally doubles the buffer size, and getsockopt reports the doubled size
- printf("send buffer size = %u (doubled, actually %u)\n", send_buffer_size, send_buffer_size/2);
- if(socket == -1)
- {
- puts("no good");
- exit(1);
- }
- char *buf = new char[max_size]; // uninitialized contents, but who cares
- for(unsigned int size = 65536; size <= max_size; size += 16384)
- {
- printf("attempting to send %u bytes\n", size);
- do_send(socket, buf, size);
- }
- puts("all done");
- delete buf;
- }
- int main()
- {
- if(fork() > 0) server(); else client();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement