Linux下UDP的連線程式示例(阻塞、非阻塞)
阿新 • • 發佈:2019-01-01
由於前面已有介紹,關於函式就不介紹了
/*server.c_非阻塞式*/ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/socket.h> #include <unistd.h> #include <netinet/in.h> #include <arpa/inet.h> #include <errno.h> #include <fcntl.h> #define SIZE 512 int sock_bind(int lisfd, int port) { struct sockaddr_in myaddr; memset((char *)&myaddr, 0, sizeof(struct sockaddr_in));//清零 myaddr.sin_family = AF_INET;//IPV4 myaddr.sin_port = htons(port);//埠 myaddr.sin_addr.s_addr = htonl(INADDR_ANY);//允許連線到所有本地地址上 if (bind(lisfd, (struct sockaddr *)&myaddr, sizeof(struct sockaddr))==-1) { perror("sock_bind failed!\n"); exit(1); } return 0; } int main(int argc, char **argv) { if (argc != 2) { printf("Usage: %s <port>\n", argv[0]); exit(1); } int lisfd; int i; int flag; int nbytes; socklen_t len; char msg[SIZE]; struct sockaddr_in cliaddr; bzero(msg, SIZE); len = sizeof(cliaddr); bzero(&cliaddr, sizeof(cliaddr)); lisfd = socket(AF_INET, SOCK_DGRAM, 0); if (lisfd == -1) { perror("socket failed.\n"); exit(1); } sock_bind(lisfd, atoi(argv[1])); flag = fcntl(lisfd, F_GETFL, 0); if (flag < 0) { perror("fcntl failed.\n"); exit(1); } flag |= O_NONBLOCK; if (fcntl(lisfd, F_SETFL, flag) < 0) { perror("fcntl failed.\n"); exit(1); } while(1) { nbytes = recvfrom(lisfd, msg, SIZE, 0, (struct sockaddr *)&cliaddr, &len); if (nbytes == -1 && errno != EAGAIN) { perror("recv failed.\n"); exit(1); }else if (nbytes == 0 || (nbytes==-1 && errno==EAGAIN)) { continue; }else { printf("recv: %s\n", msg); } for (i=0; i<strlen(msg); i++)//接收到的字元轉換為大寫的回送給客戶端 { msg[i] = toupper(msg[i]); } nbytes = sendto(lisfd, msg, sizeof(msg), 0, (struct sockaddr *)&cliaddr, len);//udp傳送要指定IP和埠 if (nbytes == -1 && errno != EAGAIN) { perror("recv failed.\n"); exit(1); } } close(lisfd); return 0; }
/*server.c_阻塞式*/ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/socket.h> #include <unistd.h> #include <netinet/in.h> #include <arpa/inet.h> #define SIZE 512 int sock_bind(int lisfd, int port) { struct sockaddr_in myaddr; memset((char *)&myaddr, 0, sizeof(struct sockaddr_in));//清零 myaddr.sin_family = AF_INET;//IPV4 myaddr.sin_port = htons(port);//埠 myaddr.sin_addr.s_addr = htonl(INADDR_ANY);//允許連線到所有本地地址上 if (bind(lisfd, (struct sockaddr *)&myaddr, sizeof(struct sockaddr))==-1) { perror("sock_bind failed!\n"); exit(1); } return 0; } int main(int argc, char **argv) { if (argc != 2) { printf("Usage: %s <port>\n", argv[0]); exit(1); } int lisfd; int i; socklen_t len; char msg[SIZE]; struct sockaddr_in cliaddr; bzero(msg, SIZE); len = sizeof(cliaddr); bzero(&cliaddr, sizeof(cliaddr)); lisfd = socket(AF_INET, SOCK_DGRAM, 0); if (lisfd == -1) { perror("socket failed.\n"); exit(1); } sock_bind(lisfd, atoi(argv[1])); while(1) { recvfrom(lisfd, msg, SIZE, 0, (struct sockaddr *)&cliaddr, &len); printf("recv: %s\n", msg); for (i=0; i<strlen(msg); i++)//接收到的字元轉換為大寫的回送給客戶端 { msg[i] = toupper(msg[i]); } sendto(lisfd, msg, sizeof(msg), 0, (struct sockaddr *)&cliaddr, len);//udp傳送要指定IP和埠 } close(lisfd); return 0; }
/*client.c*/ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/socket.h> #include <unistd.h> #include <netinet/in.h> #include <arpa/inet.h> #define SIZE 512 int main(int argc, char **argv) { struct sockaddr_in remoaddr; struct sockaddr_in localaddr; if (argc != 3) { printf("Usage: %s <server_ipaddr> <port>\n", argv[0]); exit(1); } int sockfd; char msg[SIZE]; socklen_t len; bzero(msg, SIZE); sockfd = socket(AF_INET, SOCK_DGRAM, 0); len = sizeof(localaddr); remoaddr.sin_family = AF_INET; remoaddr.sin_port = htons(atoi(argv[2])); if (inet_pton(AF_INET, argv[1], &remoaddr.sin_addr)<0) { perror("inet_pton failed.\n"); exit(1); } while(fgets(msg, SIZE, stdin) != NULL) { sendto(sockfd, msg, SIZE, 0, (struct sockaddr *)&remoaddr, len);//udp傳送要指定IP和埠 recvfrom(sockfd, msg, SIZE, 0, (struct sockaddr *)&localaddr, &len); printf("recv: %s\n", msg); } close(sockfd); return 0; }
#makefile
CFLAGS = -Wall -g
CC = gcc
TARGET1 = server
TARGET2 = client
all:$(TARGET1) $(TARGET2)
$(TARGET1):$(TARGET1).o
$(CC) $(CFLAGS) -o [email protected] $^
$(TARGET2):$(TARGET2).o
$(CC) $(CFLAGS) -o [email protected] $^
%.o:%.c %.h
$(CC) -c $(CFLAGS) -o [email protected] $<
clean:
rm -f $(TARGET1) $(TARGET2) *.o