linux网络编程实例
获取服务器时间
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> #define HOSTNAMELEN 40 #define BUFLEN 1024 #define PORT 13 int main(int argc, char *argv[]) { int rc; int sockfd; char buf[BUFLEN+1]; char *pc; struct sockaddr_in sa; struct hostent *hen; if (argc < 2) { fprintf(stderr, "missing host name\n"); exit(1); } hen = gethostbyname(argv[1]); if (!hen) { perror("could not resolve host name"); exit(1); } memset(&sa, 0, sizeof(sa)); sa.sin_family = AF_INET; sa.sin_port = htons(PORT); memcpy(&sa.sin_addr.s_addr, hen->h_addr_list[0], hen->h_length); sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) { perror("socket()"); exit(1); } rc = connect(sockfd, (struct sockaddr*)&sa, sizeof(sa)); if (rc < 0) { perror("connect()"); exit(1); } pc = buf; while (rc = read(sockfd, pc, BUFLEN - (pc-buf))) { pc += rc; } close(sockfd); *pc = '\0'; printf("time: %s\n", buf); return 0; }
tcp服务器端
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #define PORT 8888 #define BACKLOG 1 int main() { int listenfd, connfd; struct sockaddr_in servaddr; struct sockaddr_in cliaddr; int sin_size; //socket if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket()"); exit(1); } //set socket can be reuse int opt = SO_REUSEADDR; setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); //bind memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(PORT); if (bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) == -1) { perror("bind()"); exit(1); } //listen if (listen(listenfd, BACKLOG) == -1) { perror("listen()"); exit(1); } //accept sin_size = sizeof(cliaddr); if ((connfd = accept(listenfd, (struct sockaddr*)&cliaddr, &sin_size)) = = -1) { perror("accept()"); exit(1); } //print client ip printf("get a connection from %s\n", inet_ntoa(cliaddr.sin_addr)); //send char *msg = "welcome to server"; send(connfd, msg, strlen(msg), 0); //close close(connfd); close(listenfd); return 0; }
tcp客户端
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> #define PORT 8888 #define MAXDATASIZE 100 int main(int argc, char *argv[]) { int fd, numbytes; char buf[MAXDATASIZE]; struct hostent *he; struct sockaddr_in servaddr; if (argc != 2) { printf("usage: %s <ip>\n", argv[0]); exit(1); } if ((he = gethostbyname(argv[1])) == NULL) { perror("gethostbyname()"); exit(1); } if ((fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket()"); exit(1); } bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(PORT); servaddr.sin_addr = *((struct in_addr *)he->h_addr); if (connect(fd, (struct sockaddr*)&servaddr, sizeof(servaddr)) == -1) { perror("connect()"); exit(1); } if ((numbytes = recv(fd, buf, MAXDATASIZE, 0)) == -1) { perror("recv()"); exit(1); } buf[numbytes] = 0; printf("server message: %s\n", buf); close(fd); return 0; }
udp服务器端
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #define PORT 8888 #define LINESIZE 100 int main() { int sockfd; struct sockaddr_in servaddr; struct sockaddr_in cliaddr; int sin_size; int num; char msg[LINESIZE]; if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { perror("socket()"); exit(1); } memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(PORT); if (bind(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) == -1) { perror("bind()"); exit(1); } sin_size = sizeof(cliaddr); while (1) { num = recvfrom(sockfd, msg, LINESIZE, 0, (struct sockaddr*)&cliaddr, &sin_size); if (num < 0) { perror("recvfrom()"); exit(1); } msg[num] = 0; printf("you got a message (%s) from %s\n", msg, inet_ntoa(cliaddr.sin_addr)); char *msg1 = "welcome to server."; sendto(sockfd, msg1, strlen(msg1), 0, (struct sockaddr*)&cliaddr, sin_size); if (!strcmp(msg, "quit")) break; } close(sockfd); return 0; }
udp客户端
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #define PORT 8888 #define LINESIZE 100 int main(int argc, char *argv[]) { int fd, numbytes; char buf[LINESIZE]; struct hostent *he; struct sockaddr_in servaddr, reply; if (argc != 3) { printf("usage: %s <ip> <message>\n", argv[0]); exit(1); } if ((he = gethostbyname(argv[1])) == NULL) { perror("gethostbyname()"); exit(1); } if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { perror("socket()"); exit(1); } bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(PORT); servaddr.sin_addr = *((struct in_addr*)he->h_addr); sendto(fd, argv[2], strlen(argv[2]), 0, (struct sockaddr*)&servaddr, sizeof(servaddr)); while (1) { int len; if ((numbytes = recvfrom(fd, buf, LINESIZE, 0, (struct sockaddr*)&reply, &len)) == -1) { perror("recvfrom()"); exit(1); } if (len != sizeof(reply) || memcmp((const void*)&servaddr, (const void*)& reply, len) != 0) { printf("receive message from other server.\n"); continue; } buf[numbytes] = 0; printf("server message: %s\n", buf); break; } close(fd); return 0; }
并发客户端
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #define PORT 8888 #define LINESIZE 1000 void process(FILE *fp, int sockfd); char* getmsg(char *sendline, int len, FILE *fp); int main(int argc, char *argv[]) { int fd; struct hostent *he; struct sockaddr_in servaddr; if (argc != 2) { fprintf(stderr, "usage: %s <ip>\n", argv[0]); exit(1); } if ((he = gethostbyname(argv[1])) == NULL) { perror("gethostbyname()"); exit(1); } if ((fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket()"); exit(1); } bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(PORT); servaddr.sin_addr = *((struct in_addr*)he->h_addr); if (connect(fd, (struct sockaddr*)&servaddr, sizeof(servaddr)) == -1) { perror("connect()"); exit(1); } process(stdin, fd); close(fd); return 0; } void process(FILE *fp, int sockfd) { char sendline[LINESIZE], recvline[LINESIZE]; int numbytes; printf("connected to server.\n"); printf("input name: "); if (fgets(sendline, LINESIZE, fp) == NULL) { printf("\nexit\n"); return; } send(sockfd, sendline, strlen(sendline), 0); while (getmsg(sendline, LINESIZE, fp) != NULL) { send(sockfd, sendline, strlen(sendline), 0); if ((numbytes = recv(sockfd, recvline, LINESIZE, 0)) == 0) { printf("server terminated.\n"); return; } recvline[numbytes] = 0; printf("server message: %s\n", recvline); } printf("\nexit\n"); } char* getmsg(char *sendline, int len, FILE *fp) { printf("input string to server: "); return (fgets(sendline, LINESIZE, fp)); }
并发服务器端--fork
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #define PORT 8888 #define BACKLOG 2 #define LINESIZE 1000 void process_cli(int connfd, struct sockaddr_in cliaddr) { int num; char recvbuf[LINESIZE], sendbuf[LINESIZE]; char cli_name[LINESIZE]; printf("you got a connection from %s\n", inet_ntoa(cliaddr.sin_addr)); num = recv(connfd, cli_name, LINESIZE, 0); if (num == 0) { close(connfd); printf("client disconnected.\n"); return; } cli_name[num-1] = 0; printf("client's name is %s.\n", cli_name); while (num = recv(connfd, recvbuf, LINESIZE, 0)) { recvbuf[num] = 0; printf("received client(%s) message: %s", cli_name, recvbuf); int i; for (i = 0; i < num-1; i++) { sendbuf[i] = recvbuf[num-i-2]; } sendbuf[num-1] = 0; send(connfd, sendbuf, strlen(sendbuf), 0); } close(connfd); } int main() { int listenfd, connfd; pid_t pid; struct sockaddr_in servaddr; struct sockaddr_in cliaddr; int sin_size; if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket()"); exit(1); } bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(PORT); servaddr.sin_addr.s_addr = htonl(INADDR_ANY); if (bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) == -1) { perror("bind()"); exit(1); } if (listen(listenfd, BACKLOG) == -1) { perror("listen()"); exit(1); } sin_size = sizeof(cliaddr); while (1) { if ((connfd = accept(listenfd, (struct sockaddr*)&cliaddr, &sin_ size)) == -1) { perror("accept()"); exit(1); } if ((pid = fork()) > 0) { close(connfd); continue; } else if (pid == 0) { close(listenfd); process_cli(connfd, cliaddr); exit(0); } else { printf("fork error.\n"); exit(0); } } close(listenfd); return 0; }
并发服务器端--thread
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <pthread.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #define PORT 8888 #define BACKLOG 5 #define LINESIZE 1000 void process_cli(int connfd, struct sockaddr_in cliaddr); void* start_routine(void *arg); struct ARG { int connfd; struct sockaddr_in client; }; int main() { int listenfd, connfd; pthread_t th; struct ARG *arg; struct sockaddr_in servaddr; struct sockaddr_in cliaddr; int sin_size; if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket()"); exit(1); } bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(PORT); servaddr.sin_addr.s_addr = htonl(INADDR_ANY); if (bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) == -1) { perror("bind()"); exit(1); } if (listen(listenfd, BACKLOG) == -1) { perror("listen()"); exit(1); } sin_size = sizeof(cliaddr); while (1) { if ((connfd = accept(listenfd, (struct sockaddr*)&cliaddr, &sin_size)) == -1) { perror("accept()"); exit(1); } arg = malloc(sizeof(struct ARG)); arg->connfd = connfd; memcpy((void*)&arg->client, &cliaddr, sizeof(cliaddr)); if (pthread_create(&th, NULL, start_routine, (void*)arg)) { perror("pthread_create()"); exit(1); } } close(listenfd); } void process_cli(int connfd, struct sockaddr_in cliaddr) { int num; char recvbuf[LINESIZE], sendbuf[LINESIZE]; char cli_name[LINESIZE]; printf("you got a connection from %s.\n", inet_ntoa(cliaddr.sin_addr)); num = recv(connfd, cli_name, LINESIZE, 0); if (num == 0) { close(connfd); printf("client disconnected.\n"); return; } cli_name[num-1] = 0; printf("client's name is %s.\n", cli_name); while (num = recv(connfd, recvbuf, LINESIZE, 0)) { recvbuf[num] = 0; printf("received client(%s) message: %s", cli_name, recvbuf); int i; for (i = 0; i < num-1; i++) { sendbuf[i] = recvbuf[num-i-2]; } sendbuf[num-1] = 0; send(connfd, sendbuf, strlen(sendbuf), 0); } close(connfd); } void* start_routine(void *arg) { struct ARG *info; info = (struct ARG*)arg; process_cli(info->connfd, info->client); free(arg); pthread_exit(NULL); }
并发服务器端--select
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <sys/time.h> #define PORT 8888 #define BACKLOG 5 #define LINESIZE 1000 typedef struct { int fd; char *name; struct sockaddr_in addr; char *data; } CLIENT; void process_cli(CLIENT *client, char *recvbuf, int len); void savedata(char *recvbuf, int len, char *data); int main() { int i, maxi, maxfd, sockfd; int nready; ssize_t n; fd_set rset, allset; int listenfd, connfd; struct sockaddr_in servaddr; CLIENT client[FD_SETSIZE]; char recvbuf[LINESIZE]; int sin_size; if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket()"); exit(1); } int opt = SO_REUSEADDR; setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(PORT); servaddr.sin_addr.s_addr = htonl(INADDR_ANY); if (bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) == -1) { perror("bind()"); exit(1); } if (listen(listenfd, BACKLOG) == -1) { perror("listen()"); exit(1); } sin_size = sizeof(struct sockaddr_in); maxfd = listenfd; maxi = -1; for (i = 0; i < FD_SETSIZE; i++) { client[i].fd = -1; } FD_ZERO(&allset); FD_SET(listenfd, &allset); while (1) { struct sockaddr_in addr; rset = allset; nready = select(maxfd+1, &rset, NULL, NULL, NULL); if (FD_ISSET(listenfd, &rset)) { if ((connfd = accept(listenfd, (struct sockaddr*)&addr, &sin_size)) == -1) { perror("accept()"); continue; } for (i = 0; i < FD_SETSIZE; i++) if (client[i].fd < 0) { client[i].fd = connfd; client[i].name = malloc(LINESIZE); client[i].addr = addr; client[i].data = malloc(LINESIZE); client[i].name[0] = 0; client[i].data[0] = 0; printf("you got a connection from %s.\n" , inet_ntoa(client[i].addr .sin_addr)); break; } if (i == FD_SETSIZE) printf("too many clients\n"); FD_SET(connfd, &allset); if (connfd > maxfd) maxfd = connfd; if (i > maxi) maxi = i; if (--nready <= 0) continue; } for (i = 0; i <= maxi; i++) { if ((sockfd = client[i].fd) < 0) continue; if (FD_ISSET(sockfd, &rset)) { if ((n = recv(sockfd, recvbuf, LINESIZE, 0)) == 0) { close(sockfd); printf("client (%s) closed connection. u ser's data: %s\n", client[i].name, client[i ].data); FD_CLR(sockfd, &allset); client[i].fd = -1; free(client[i].name); free(client[i].data); } else process_cli(&client[i], recvbuf, n); if (--nready <= 0) break; } } } close(listenfd); return 0; } void process_cli(CLIENT *client, char *recvbuf, int len) { char sendbuf[LINESIZE]; recvbuf[len-1] = 0; if (strlen(client->name) == 0) { memcpy(client->name, recvbuf, len); printf("client's name is %s.\n", client->name); return; } printf("received client(%s) message: %s\n", client->name, recvbuf); savedata(recvbuf, len, client->data); int i1; for (i1 = 0; i1 < len-1; i1++) { sendbuf[i1] = recvbuf[len-i1-2]; } sendbuf[len-1] = 0; send(client->fd, sendbuf, strlen(sendbuf), 0); } void savedata(char *recvbuf, int len, char *data) { int start = strlen(data); int i; for (i = 0; i < len; i++) { data[start+i] = recvbuf[i]; } }