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 $@ $^
$(TARGET2):$(TARGET2).o
		$(CC) $(CFLAGS) -o $@ $^
%.o:%.c %.h
		$(CC) -c $(CFLAGS) -o $@ $<
clean:
		rm -f $(TARGET1) $(TARGET2) *.o


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值