Network client/server

时间:2025-02-02 17:35:14

<Beginning Linux Programming_4th>  chapter 15 Sockets

1  A simple local client/server

1)  client.c

// 1) header files
// int socket(int domain, int type, int protocol);
#include <sys/types.h>
// int connect(int socket, const struct sockaddr*address,size_t address_len);
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
/* struct sockaddr_in{
short int sin_family; // AF_INET
unsigned short int sin_port; // Port number
struct in_addr sin_addr; //Internet address
}; */
#include <netinet/in.h>
#include <arpa/inet.h>
// size_t write(int fildes, const void *buf, size_t nbytes);
// size_t read(int fildes, const void *buf, size_t nbytes);
#include <unistd.h> // 2) socket
int main ()
{
// 127.0.0.1 loopback network
// 192.168.1.1 local area network via an Ethernet adaptor
// 158.152.x.x modem link to an Internet service provider
int sockfd;
int len;
struct sockaddr_in address;
int result;
char ch = 'A'; /* struct in_addr{
unsigned long int s_addr;
}; */
sockfd = socket(AF_INET, SOCK_STREAM, );
address.sin_family = AF_INET;
address.sin_addr.s_addr = inet_addr("127.0.0.1");
address.sin_port = htons();
len = sizeof(address);
/* sizeof(变量/数据类型); // 结果是一个整数
变量或此种数据类型的变量所占的内存空间字节数
printf("the size of char is %d bytes\n", sizeof(char)); */
// 3) connect
result = connect(sockfd, (struct sockaddr*) &address, len);
if(result == -)
{
perror("oops: client");
exit();
} // 4) write, read and close
write(sockfd, &ch, );
read(sockfd, &ch, );
printf("char from server = %c\n", ch); close(sockfd);
exit();
} /* convert 16-bit/32-bit integers between host and network ordering
<netinet/in.h>
unsigned long int htol(unsigned long int hostlong);
unsigned short int htos(unsigned short int hostshort);
unsigned long int ntohl(unsigned long int netlong);
unsigned short int ntohs(unsigned short int netshort);

2)  server.c

// 1)  header files
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h> // 2) socket
int main()
{
int server_sockfd, client_sockfd;
int server_len, client_len; struct sockaddr_in server_address;
struct sockaddr_in client_address;
unlink("server_socket"); server_sockfd = socket(AF_INET, SOCK_STREAM, );
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = htonl(INADDR_ANY);
server_address.sin_port = htons();
server_len = sizeof(server_address); // 3) bind, listen
bind(server_sockfd, (struct sockaddr*)&server_address, server_len);
listen(server_sockfd, ); // 4) while loop: accept - read/write - close
while()
{
char ch;
printf("server waiting\n");
client_len = sizeof(client_address);
client_sockfd = accept(server_sockfd, (struct sockaddr*)&client_address, &client_len); read(client_sockfd, &ch, );
ch++;
write(client_sockfd, &ch,); close(client_sockfd);
}
}
// int bind(int socket, const struct sockaddr* address, size_t address_len);
// int listen(int socket, int backlog);
// int accept(int socket, struct sockaddr* address, size_t* address_len);

2  A server for multiple clients

server2.c

// 1)  header files
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <signal.h>
#include <unistd.h> // 2) socket
int main()
{
int server_sockfd, client_sockfd;
int server_len, client_len; struct sockaddr_in server_address;
struct sockaddr_in client_address; server_sockfd = socket(AF_INET, SOCK_STREAM, );
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = htonl(INADDR_ANY);
server_address.sin_port = htons();
server_len = sizeof(server_address); // 3) bind, listen, signal
bind(server_sockfd, (struct sockaddr*)&server_address, server_len);
listen(server_sockfd, );
signal(SIGCHLD, SIG_IGN); // 4) while loop: accept - fork
while()
{
char ch;
printf("server waiting\n");
client_len = sizeof(client_address);
client_sockfd = accept(server_sockfd, (struct sockaddr*)&client_address, &client_len); if(fork() == )
{
read(client_sockfd, &ch, );
sleep();
ch++;
write(client_sockfd, &ch,);
close(client_sockfd);
exit();
}
else
{
close(client_sockfd);
}
}
}

3  An improved server for multiple clients

server3.c

// header files
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <unistd.h> // 1) socket
int main()
{
int server_sockfd, client_sockfd;
int server_len, client_len; struct sockaddr_in server_address;
struct sockaddr_in client_address; int result;
fd_set readfds, testfds; server_sockfd = socket(AF_INET, SOCK_STREAM, );
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = htonl(INADDR_ANY);
server_address.sin_port = htons();
server_len = sizeof(server_address); // 2) bind, listen
bind(server_sockfd, (struct sockaddr*)&server_address, server_len);
listen(server_sockfd, );
FD_ZERO(&readfds);
FD_SET(server_sockfd, &readfds); // 3) while loop: server activity, client activity
while()
{
char ch;
int fd;
int nread;
testfds = readfds;
printf("server waiting\n");
result = select(FD_SETSIZE, &testfds, (fd_set*), (fd_set*), (struct timeval*)); if(result<){
perror("server");
exit();
} for(fd=; fd<FD_SETSIZE; fd++)
{
if(FD_ISSET(fd, &testfds))
{
if(fd==server_sockfd)
{
client_len = sizeof(client_address);
client_sockfd = accept(server_sockfd, (struct sockaddr*)&client_address, &client_len);
FD_SET(client_sockfd, &readfds);
printf("adding client an fd %d\n", client_sockfd);
}
else
{
ioctl(fd, FIONREAD, &nread); if(nread==)
{
close(fd);
FD_CLR(fd, &readfds);
printf("removing client on fd %d\n", fd);
}
else
{
read(fd, &ch, );
sleep();
printf("serving client on fd %d\n", fd);
ch++;
write(fd, &ch, );
}
} // 1st if
} // 2nd if
} //for
} // while
} // main

小结:

client: socket -- connect --r/w -- close

server: socket -- bind -- listen -- accept -- r/w -- close

while(1)

server2: socket -- bind -- listen -- signal -- accept -- fork

while(1)