网络基础 UDP协议

UDP协议端格式


  • 16位UDP长度, 表⽰整个数据报(UDP⾸部+UDP数据)的最⼤⻓度;
  • 如果校验和出错, 就会直接丢弃;

UDP特点

UDP传输的过程类似于寄信.
  • ⽆连接: 知道对端的IP和端口号就直接进行传输, 不需要建立连接;
  • 不可靠: 没有确认机制, 没有重传机制; 如果因为网络故障该段无法发到对方, UDP协议层也不会给;
  • 应⽤层返回任何错误信息;
  • ⾯向数据报: 不能够灵活的控制读写数据的次数和数量;

编写简单的UDP服务器

其功能为可以接收客户端消息,并可以返回给客户端一条消息。

服务器

#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<string.h>
#include<stdlib.h>
#include<arpa/inet.h>
#include<unistd.h>

//./service 192.168.1.113 8888

int main(int argc,char* argv[])
{
	if(argc != 3)
	{
		printf("Usage:%s [ip] [port]\n");
		return 1;
	}
	int sock = socket(AF_INET,SOCK_DGRAM,0);
	{
		if(sock < 0)
		{
			printf("sock error\n");
			return 2;
		}
	}
	struct sockaddr_in local;
	local.sin_family = AF_INET;
	local.sin_addr.s_addr = inet_addr(argv[1]);  //将一个点分十进制转换成一个长整数
	local.sin_port = htons(atoi(argv[2]));  //atoi把字符串转换成整型数  htons 大小端转换
	
	if(bind(sock,(struct sockaddr*)&local,sizeof(local)) < 0)
	{
		printf("bind error!\n");
		return 3;
	}
	
	char buf[1024];
	struct sockaddr_in client;
	while(1)
	{
		socklen_t len = sizeof(client);
		ssize_t s = recvfrom(sock,buf,sizeof(buf)-1,0,(struct sockaddr*)&client,&len);
		if(s > 0)
		{
			buf[s] = 0;
			//printf("[client echo#] %s\n",buf);
			printf("[%s | %d]: %s\n",inet_ntoa(client.sin_addr),ntohs(client.sin_port),buf);
			printf("[please enter#]");
		}
		fflush(stdout);
		ssize_t _s = read(0,buf,sizeof(buf)-1);
		sendto(sock,buf,strlen(buf),0,(struct sockaddr*)&client,sizeof(client));
		printf("\n=====================================\n");
	}
}

客户端

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <unistd.h>

//./client 192.168.1.113 8888
int main(int argc,char* argv[])
{
	if(argc != 3)
	{
		printf("Usage:%s [ip] [port]\n",argv[0]);
		return 2;
	}
	int sock = socket(AF_INET,SOCK_DGRAM,0);
	if(sock < 0)
	{
		printf("socket error!\n");
		return 1;
	}
	struct sockaddr_in server;
	server.sin_family = AF_INET;
	server.sin_port = htons(atoi(argv[2]));
	server.sin_addr.s_addr = inet_addr(argv[1]);

	char buf[1024];
	struct sockaddr_in peer;
	while(1)
	{
		socklen_t len = sizeof(peer);
		printf("[please enter#] ");
		fflush(stdout);
		ssize_t s = read(0,buf,sizeof(buf)-1);
		if(s > 0)
		{
			buf[s-1] = 0;
			sendto(sock,buf,strlen(buf),0,(struct sockaddr*)&server,sizeof(server));
			ssize_t _s = recvfrom(sock,buf,sizeof(buf)-1,0,(struct sockaddr*)&peer,&len);
			if(_s > 0)
			{
				buf[_s] = 0;
				printf("[server echo#] %s\n",buf);
				printf("======================================\n");
			}
		}
	}
	close(sock);
	return 0;
}

makefile:

.PHONY:all
all:service client
service:service.c
gcc -o $@ $^
client:client.c
gcc -o $@ $^ -static
.PHONY:clean
clean:
rm -f service client

运行演示:

未输入ip地址及端口号,列出提示:

服务器:


客户端:

    可以发现,客户端和服务器之间可以实现信息交流。如果将客户端在A电脑启动,在同一局域网下的B电脑打开客户端,也可以实现交流。

    如果需要将客户端传给其他电脑,则需要关闭防火墙,并用scp发送过去

关闭防火墙:
sudo service iptables stop
远程拷贝:
scp命令:scp client 192.168.1.112:/home 

client是需要传递的文件名

192.168.1.112是目标IP地址,IP地址与:/home之间无空格




猜你喜欢

转载自blog.csdn.net/ihaha233/article/details/80320304
今日推荐