网络编程值UDP

1. 知识点

1.1 TCP和UDP优缺点

1.2 UDP通信流程

1.2.1 服务端

1. 创建udp套接字

2. 初始化服务端网络地址结构  

3. 绑定服务端网络地址

4.创建结构体用来存储客户端网络地址结构

5. 接收客户数据

1.2.2 客户端

1. 创建udp套接字

2. 初始化服务器网络地址结构

3. 客户端先发送数据

2. 函数接口参考course-1

3. udp通信的接收和发送

udp_server.c

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

//udp通信
//服务端 和客户端 接收发送信息

int main(int argc,char** argv)
{
    //1. 创建udp套接字
    int socket_fd = socket(AF_INET,SOCK_DGRAM,0);
    if(socket_fd == -1){
        printf("创建套接字失败\n");
        return -1;
    }

    //2. 初始化服务端网络地址结构  //4.创建结构体cliaddr用来存储客户端网络地址结构
    struct sockaddr_in cliaddr,seraddr;//cliaddr客户  seraddr服务
    //初始化服务端地址
    seraddr.sin_family = AF_INET;
    seraddr.sin_port = htons(atoi(argv[2]));//设置端口 //主机字节序的短整型数据
    seraddr.sin_addr.s_addr = inet_addr(argv[1]);//将将点分十进制转转为无符号的32位网络地址

    socklen_t seraddr_len = sizeof(seraddr);
	socklen_t cliaddr_len = sizeof(cliaddr);

    //3. 绑定服务端网络地址
    int bind_ok = bind(socket_fd,(struct sockaddr*)&seraddr,seraddr_len);
    if(bind_ok==-1){
        perror("bind failed");
    }

    //监听,可有可无
    listen(socket_fd,4);

    char sbuf[128];//发送
    char rbuf[128];//接收

    while(1){

        memset(sbuf,0,sizeof(sbuf));
        memset(rbuf,0,sizeof(rbuf));

        //5. 接收客户数据,这里先接收客户发送的消息,第五个参数可以得到客户的地址
        recvfrom(socket_fd,rbuf,sizeof(rbuf),0,(struct sockaddr *)&cliaddr,&cliaddr_len);
        printf("server接收数据:%s\n",rbuf);

        //发送,发送个客户,因为我们recvfrom函数接收已经得到了客户地址了
        fgets(sbuf,sizeof(sbuf),stdin);
        sendto(socket_fd,sbuf,sizeof(sbuf),0,(struct sockaddr *)&cliaddr,cliaddr_len);
        printf("server发送数据:%s\n",sbuf);

        
        //退出
        if(strcmp("bye\n",sbuf)==0){
            break;
        }

        //退出
        if(strcmp("bye\n",rbuf)==0){
            break;
        }
    }   

    close(socket_fd);
    
    return 0;
}

udp_client.c

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

//udp通信
//客户端 和 服务端 发送接收信息

int main(int argc,char** argv)
{
    //1. 创建udp套接字
    int socket_fd = socket(AF_INET,SOCK_DGRAM,0);
    if(socket_fd == -1){
        printf("创建套接字失败\n");
        return -1;
    }

    //2. 初始化服务器网络地址结构
    struct sockaddr_in seraddr;//cliaddr客户  seraddr服务

    seraddr.sin_family = AF_INET;
    seraddr.sin_port = htons(atoi(argv[2]));//设置端口 //主机字节序的短整型数据
    seraddr.sin_addr.s_addr = inet_addr(argv[1]);//将将点分十进制转转为无符号的32位网络地址
    socklen_t seraddr_len = sizeof(seraddr);


    //这个绑定可有可无
    // struct sockaddr_in cliaddr;
	// socklen_t cliaddr_len = sizeof(cliaddr);
    // int bind_ok = bind(socket_fd,(struct sockaddr*)&cliaddr,cliaddr_len);
    // if(bind_ok==-1){
    //     perror("bind failed");
    // }

    //监听,可有可无
    listen(socket_fd,4);

    char sbuf[128];//发送
    char rbuf[128];//接收

    while(1){

        memset(sbuf,0,sizeof(sbuf));
        memset(rbuf,0,sizeof(rbuf));

        //3. 客户端先发送数据,发给服务端,因为上面我们初始化了服务器地址结构
        fgets(sbuf,sizeof(sbuf),stdin);
        sendto(socket_fd,sbuf,sizeof(sbuf),0,(struct sockaddr *)&seraddr,seraddr_len);
        printf("client发送数据:%s\n",sbuf);

        //接收服务端数据
        recvfrom(socket_fd,rbuf,sizeof(rbuf),0,(struct sockaddr *)&seraddr,&seraddr_len);
        printf("client接收数据:%s\n",rbuf);
        
        //退出
        if(strcmp("bye\n",sbuf)==0){
            break;
        }
        
        //退出
        if(strcmp("bye\n",rbuf)==0){
            break;
        }
    }   

    close(socket_fd);
    
    return 0;
}

4. 可以将 通信的双发 接收和发送 写在一起

whole_udp.c

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

int sock_fd = -1;

void *recv_addr2(void *arg)
{
	struct sockaddr outside_addr = *(struct sockaddr *)arg;
	
	socklen_t addr2_len = sizeof(outside_addr);
	char sbuf[128];
	while(1)
	{
		memset(sbuf,0,sizeof(sbuf));

		fgets(sbuf,sizeof(sbuf),stdin);
		sendto(sock_fd,sbuf,sizeof(sbuf),0,(struct sockaddr *)&outside_addr,addr2_len);
	}
}

int main(int argc, char **argv)
{
	//创建udp套接字
	sock_fd = socket(AF_INET,SOCK_DGRAM,0);
	
	//定义结构体
	struct sockaddr_in local_addr, outside_addr;
	
	//自己本地的地址信息
	local_addr.sin_family = AF_INET;
	local_addr.sin_port = htons(atoi(argv[2]));
	local_addr.sin_addr.s_addr = inet_addr(argv[1]);
	//计算本地大小
	socklen_t local_addr_len = sizeof(local_addr);
	//绑定本地
	bind(sock_fd,(struct sockaddr *)&local_addr,local_addr_len);
	
	//外地地址信息
	outside_addr.sin_family = AF_INET;
	outside_addr.sin_port = htons(atoi(argv[4]));
	outside_addr.sin_addr.s_addr = inet_addr(argv[3]);
	//计算外地大小
	socklen_t outside_addr_len = sizeof(outside_addr);

	//监听 ,可有可无
	listen(sock_fd,4);
	
	//创建线程
	pthread_t tid;
	//传参把外地地址信息传到线程函数中
	pthread_create(&tid,NULL,recv_addr2,(void *)&outside_addr);
	
	char rbuf[128];//接收
	
	while(1)
	{

		memset(rbuf,0,sizeof(rbuf));

		//接收,接收外地信息
		recvfrom(sock_fd,rbuf,sizeof(rbuf),0,(struct sockaddr *)&outside_addr,&outside_addr_len);

		//将是一个用于将 IPv4 地址从二进制形式转换为点分十进制字符串形式的C库函数。
		char *ip = inet_ntoa(outside_addr.sin_addr);//ip
		unsigned short port = ntohs(outside_addr.sin_port);//端口号
		
		printf("[来自%s  %u outside_addr]:%s\n",ip,port,rbuf);
	}

	
}

  • 13
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Socket网络编程是一种在计算机网络中进行数据交互的编程方式。通过使用Socket,我们可以在不同的计算机之间建立网络连接并进行数据传输。 在C语言中,我们可以使用标准库中的socket函数来创建一个Socket。首先,我们需要使用socket函数来创建一个Socket套接字,指定协议和类型。然后,使用bind函数将Socket与一个本地地址绑定,通常是一个IP地址和一个端口号。接着,使用listen函数启动Socket的监听模式,等待其他计算机发起连接请求。 一旦有其他计算机发起连接请求,我们可以使用accept函数来接受连接,并返回一个新的Socket文件描述符,这个新的Socket可以用于与对方进行数据交互。在这之后,我们可以使用send和recv函数来发送和接收数据。 当数据发送完毕或接收完毕后,我们可以使用close函数关闭Socket,释放资源。在进行Socket网络编程时,我们还可以使用select函数来实现多路复用,同时监听多个Socket,提高程序的效率。 在Socket网络编程中,还可以使用一些其他的函数来设置Socket的各种属性,例如设置Socket为非阻塞模式,设置等待时间等。 总之,Socket网络编程提供了一个方便的方式来进行网络通信。通过使用Socket函数及其相关函数,我们可以在C语言中轻松实现网络编程,实现不同计算机之间的数据交互。 ### 回答2: c socket网络编程是一种用C语言编写的网络编程技术,它允许计算机之间通过网络进行通信和数据交换。在C语言中,socket函数库提供了一种方便的方式来创建网络应用程序。 使用C socket网络编程,我们可以通过创建一个套接字(socket)来建立与其他计算机的连接。套接字可以视为两个应用程序之间的通信端口。一个应用程序可以充当服务器(server),等待其他应用程序的连接请求,并接受它们的连接。另一个应用程序可以充当客户端(client),向服务器发送连接请求,并与服务器建立连接。一旦连接建立,我们可以在客户端和服务器之间传递数据。 在进行C socket网络编程时,我们需要使用一些重要的函数,如socket、bind、listen、accept、connect和send/recv等。其中,socket函数用于创建一个套接字,bind函数用于将套接字与本地IP地址和端口绑定,listen函数用于在服务器端开始监听连接请求,accept函数用于接受客户端的连接请求,connect函数用于与服务器建立连接,send/recv函数用于在已经建立的连接上发送和接收数据。 C socket网络编程在实际应用中具有广泛的用途。它可以用于开发各种类型的网络应用程序,如网络聊天室、网络游戏、文件传输、远程控制等。通过使用C socket网络编程技术,我们可以轻松地实现不同计算机之间的通信和数据交换,为用户提供更好的网络体验。 ### 回答3: C语言的socket网络编程是指利用socket库函数,通过TCP/IP协议或UDP协议在网络上进行数据通信的一种编程方式。 在C语言中,可以使用socket()函数创建一个套接字,该函数返回一个整数作为套接字的标识符。创建套接字后,可以使用bind()函数将套接字与本地的IP地址和端口号绑定起来。 对于服务器端程序,可以使用listen()函数设置套接字为监听状态,然后通过accept()函数接受客户端的连接请求。 对于客户端程序,可以使用connect()函数连接到服务器端的套接字。连接成功后,客户端可以使用send()函数发送数据给服务器端,也可以使用recv()函数接收服务器端发送过来的数据。 在网络编程中,需要注意错误处理。例如,当创建套接字或者连接失败时,需要使用perror()函数输出错误信息,并且使用close()函数关闭套接字。此外,还需要使用htons()和htonl()函数将主机字节序转换为网络字节序,以及使用ntohs()和ntohl()函数将网络字节序转换为主机字节序。 socket网络编程还可以使用多线程或多进程实现并发处理,可以同时处理多个连接请求,提高服务器的并发性能。 总之,C语言的socket网络编程是一种强大的工具,用于在网络上进行数据通信。它可以使程序与程序之间实现数据的传输和通信,方便地实现分布式系统、网络游戏、即时通信等应用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值