1. 程式人生 > >Linux下UDP的連線程式示例(阻塞、非阻塞)

Linux下UDP的連線程式示例(阻塞、非阻塞)

由於前面已有介紹,關於函式就不介紹了

/*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