UDP网络编程套接字

IP地址:

IP协议有两个版本,一个是IPv4,一个是IPv6。

IP地址是在IP协议中,用来标识网络中不同的主机的地址。

对于IPv4来说,IP地址是一个4字节,32位的整数。

源IP地址和目的IP地址:

在数据包头部的两个IP地址,一个叫源IP地址,一个叫目的IP地址

端口号port(必须是众所周知的,并且不能随意修改):

端口号是一个2个字节,16位的整数

端口号用来标识一个进程,告诉操作系统,当前的这个数据要交给那个进程来处理

IP地址 + 端口号:标识着网络上某一台主机的某一个进程。

源端口号和目的端口号:

可以基本理解为“谁发的,要发给谁”。

认识UDP:

传输层协议、无连接、不可靠传输、面向数据报

网络字节序列:

内存中多字节数据相对于内存地址有大小端之分,网络数据流同样具有大小端之分。

发送主机通常将发送缓冲区的数据按照内存地址从低脂高顺修发出,

接受主机把从网络上接收到的字节依次保存在接收缓存区中,也是按照内存地址从低到高的顺修保存,

因此,网络数据流的地址因该这样规定,先发的数据应该是低地址,后发的数据应该是高地址,

TCP/IP协议规定,网络数据流应该采用大端自己序列,即低地址高字节。


       int socket(int domain, int type, int protocol);
1.创建socket文件描述符


       int bind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen);

  2. 绑定端口号

       int listen(int s, int backlog);

3.开始监听


       int accept(int s, struct sockaddr *addr, socklen_t *addrlen);

4.接收请求

       int connect(int sockfd, const struct sockaddr *addr,
                   socklen_t addrlen);
5.建立链接




sockaddr 结构



IPv4和IPv6的地址格式定义在netinet.h中IPv4用结构体sockaddr_in表示,

IPv4和IPv6的地址类型分别定义为常数AF_INET,AF_INET6,这样只要取得了sockaddr结构体的首地址,不需要知道具体是哪一种类型的sockadr结构体,就可以根据地址类型字段确定结构体的内容。

以下是一个简单的UDP服务器。

//服务器

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

//127.0.0.1;本地环回 用于测试本地网络
//netstat -nlp  显示网络接口   比如ssh

void service(int sock)
{
    char buf[SIZE];
    while(1)
    {
        struct sockaddr_in peer;
        socklen_t len = sizeof(peer);
        buf[0] = 0;
        size_t s = recvfrom(sock,buf,sizeof(buf)-1,0,(struct sockaddr*)&peer,&len);
        if(s>0)
        {
            buf[s] = 0;
            printf("[%s:%d]# %s\n",inet_ntoa(peer.sin_addr),ntohs(peer.sin_port),buf);
            
            sendto(sock,buf,strlen(buf),0,(struct sockaddr*)&peer,len);
        }
    }
}
int main(int argc,char *argv[])
{
    if(argc != 3)
    {
        printf("Usage:%s [ip] [port]\n",argv[0]);
        return 3;
    }
    
    int sock = socket(AF_INET,SOCK_DGRAM,0);
    if(sock<0)
    {
        perror("socket");
        return 1;
    }

    struct sockaddr_in local;
    local.sin_family = AF_INET;
    local.sin_port = htons(atoi(argv[2]));
    local.sin_addr.s_addr = inet_addr(argv[1]);
    if(bind(sock,(struct sockaddr*)&local,sizeof(local))<0)
    {
        perror("bind");
        return 2;
    }
    service(sock);
    close(sock);
    return 0;
}


//客户端

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


int main(int argc,char* argv[])
{
    if(argc != 3)
    {
        printf("Usage: %s [ip] [port]\n",argv[0]);
        return 1;  
    }
    int sock = socket(AF_INET,SOCK_DGRAM,0);
    if(sock<0)
    {
        perror("socket");
        return 2;
    }
    char buf[128];
    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]);
    socklen_t len = sizeof(server);
    while(1)
    {
        buf[0] = 0;
        size_t s = read(0,buf,sizeof(buf)-1);
        if(s>0)
        {
            buf[s-1] = 0;
            sendto(sock,buf,strlen(buf),0,(struct sockaddr*)&server,len);
            s = recvfrom(sock,buf,sizeof(buf)-1,0,NULL,NULL);
            if(s>0)
            {
                buf[s] = 0;
                printf("server # %s\n",buf);
            }
        }
    }
    close(sock);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/duckyloser/article/details/80460670