网络编程 Day1-1 UDP简单实现

服务端:(提供服务的,一个服务端对于多个客户端)

1) 套接字------直接调用socket(将网络设备打开了)

2) bind(绑定)------给套接字设置端口号(主要是端口号的设置)与IP地址(本机是多少就是多少)

    ------(方便客户端连接)

3)recvfrom  ------> 先处理客户的请求-------> sendto (循环)

客户端:(使用服务的)

1) 套接字 

2)sendto <-------> recvfrom

3)  进程结束 ---- 套接字闭

server.c

1)socket

int socket(int domain, int type, int protocol);
功能:程序向内核提出创建一个基于内存的套接字描述符

参数:domain  地址族,PF_INET == AF_INET ==>互联网程序
                      PF_UNIX == AF_UNIX ==>单机程序
      type    套接字类型:
                SOCK_STREAM  流式套接字 ===》TCP   
              SOCK_DGRAM   用户数据报套接字===>UDP
              SOCK_RAW     原始套接字  ===》IP
      protocol 协议 ==》0 表示自动适应应用层协议。

返回值:成功 返回申请的套接字id
        失败  -1;

typedef struct sockaddr * (SA);//重要墙砖类型,addr_in

用户数据报: int type;

SOCK_STREAM(TCP);

SOCK_DGRAM(UDP);

int protocol ;//确定是UDP 的套接字 =0;

int sockfd=socket(AF_INET,SOCK_DGRAM,0);
if(sockfd==-1)
{
   perror("socket");
   exit(1);
}

2)bind; 

2、int bind(int sockfd, struct sockaddr *my_addr, 
             socklen_t addrlen);
功能:如果该函数在服务器端调用,则表示将参数1相关
      的文件描述符文件与参数2 指定的接口地址关联,
      用于从该接口接受数据。

      如果该函数在客户端调用,则表示要将数据从
      参数1所在的描述符中取出并从参数2所在的接口
      设备上发送出去。

      注意:如果是客户端,则该函数可以省略,由默认
            接口发送数据。
参数:sockfd 之前通过socket函数创建的文件描述符,套接字id
      my_addr 是物理接口的结构体指针。表示该接口的信息。

      struct sockaddr      通用地址结构
      {
          u_short sa_family;  地址族
          char sa_data[14];   地址信息
      };

      转换成网络地址结构如下:
      struct _sockaddr_in    ///网络地址结构
      {
          u_short           sin_family; 地址族
          u_short           sin_port;   ///地址端口
          struct in_addr  sin_addr;   ///地址IP
          char               sin_zero[8]; 占位
      };

      struct in_addr
      {
          in_addr_t s_addr;
      }

//man 7 ip; 我们所需要的地址结构体

struct socketaddr_in ser,cli;//定义互联网结构体 两个变量一个用于客户端一个用于服务端
bzero(&ser,sizeof(ser));//清空结构体
bzero(&cli,sizeof(cli));

struct socketaddr_in;
ser.sin_family=AF_INET;
ser.sin_port=htones(50000);//大小断转化host to net short
ser.sin_addr.s_addr=inet_addr("自己的ip地址");
int ret = bind(sockfd,&ser,sizeof(ser));
if( ret == -1)
{
   perror("bind");
   exit(1);
}

 3)开始收发

while(1)
{
   char buf[512]={0};
   socklen_t len=sizof(cli);
   recvfrom(sockfd,buf,sizeof(buf),&cli,&len);
   time_t tm;
   time(&tm);
   sprintf(buf,"%s %s",buf,ctime(&tm));
 
   sendto(sockfd,buf,strlen(buf),0,&cli,len);
   
}
close(sockfd);

recvfrom(从那收sockfd,收到哪buf,本次接收的最大长度sizeof(buf) ,  接受方式 默认为0 ,发送方 &cli , &len) 

sendto(从哪发网络设备发sockfd , 发谁buf , 发多大strlen(buf) , 0 发送方式默认方式(要么收到要么丢失), 发到哪&cli , len );

 ifconfig(得到自己的地址)

完整代码

server.c 

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <time.h>
typedef struct sockaddr * (SA);
int main(int argc, char *argv[])
{
    int sockfd = socket(AF_INET,SOCK_DGRAM,0);
    if(-1 == sockfd)
    {
        perror("socket");
        exit(1);
    }

    // man 7 ip 
    struct sockaddr_in ser,cli;
    bzero(&ser,sizeof(ser));
    bzero(&cli,sizeof(cli));
    ser.sin_family = AF_INET;
    // 大小端转化 host to net short 
    ser.sin_port = htons(50000);
    ser.sin_addr.s_addr = inet_addr("192.168.203.128");
    int ret = bind(sockfd,(SA)&ser,sizeof(ser));
    if(-1 == ret)
    {
        perror("bind");
        exit(1);
    }
    socklen_t len = sizeof(cli);
    while(1)
    {
        char buf[512]={0};
        recvfrom(sockfd,buf,sizeof(buf),0,(SA)&cli,&len);
        time_t tm;
        time(&tm);
        sprintf(buf,"%s %s",buf,ctime(&tm));
        sendto(sockfd,buf,strlen(buf),0,(SA)&cli,len);
    }
    close(sockfd);
    return 0;
}

client.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <time.h>
typedef struct sockaddr * (SA);


int main(int argc, char *argv[])
{
    int sockfd = socket(AF_INET,SOCK_DGRAM,0);
    if(-1 == sockfd)
    {
        perror("socket");
        exit(1);
    }
    struct sockaddr_in ser;
    bzero(&ser,sizeof(ser));
    ser.sin_family = AF_INET;
    // 大小端转化 host to net short 
    ser.sin_port = htons(50000);
    ser.sin_addr.s_addr = inet_addr("192.168.203.128");

    while(1)
    {
        char buf[512]="hello,this is udp test";
        sendto(sockfd,buf,strlen(buf),0,(SA)&ser,sizeof(ser));
        bzero(buf,sizeof(buf));
        recvfrom(sockfd,buf,sizeof(buf),0,NULL,NULL);
        printf("buf is %s\n",buf);
        sleep(1);
    }
    close(sockfd);
    return 0;
}

  • 9
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值