不得不说。。。自己懒的程度连自己都受不了。。。虽然一直在学~但处于学完又忘的状态。。。总觉得自己记完笔记又会忘掉。。。555。。。

自己正在慢慢挖掘linux下编程的兴趣,感觉处于混沌状态,都说编程这种东西都得有兴趣才可以编出来的~~希望我对它的兴趣会一直上升~~~

好好记录笔记。。。

无连接的套接字通信即UDP通信~C的实现看起来和java的代码实现差不少额。。。但总的来说,步骤都差不多。。。flashplayer版本太低了,找天补"21天linux'的图~

补上:

wKioL1LGMfOCulm-AABOyTSDn8I180.jpg

具体说法:

服务器:1.创建socket;    2.socket绑定端口;    3.读取接收到的信息;    4.发送消息

               socket()            bind()                    recvfrom()                sendto()

客户端:1.创建socket;    2.连接一个指定的计算机和端口;    3.发送消息;    4.读取接收到的信息

               socket()            bind()                                        sendto()        recvfrom()


服务器源码:

#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#define LOCALPORT 4567
                                                                                                                                                                                                        
int main(int argc, char *argv[])
{
    int mysock, len;
    struct sockaddr_in addr;
    int i = 0;
    char msg[256];
    int addr_len;
    if((mysock=socket(AF_INET, SOCK_DGRAM, 0)) < 0)
    {
        perror("error");
        exit(1);
    }
    else
    {
        printf("socket created.\n");
        printf("socket id: %d\n",mysock);
    }
    addr_len = sizeof(struct sockaddr_in);
    bzero(&addr, sizeof(addr));
    addr.sin_family=AF_INET;
    addr.sin_port=htons(LOCALPORT);
    addr.sin_addr.s_addr=htonl(INADDR_ANY);//0.0.0.0任意地址
    if(bind(mysock, &addr, sizeof(addr)) < 0)
    {
        perror("connect");
        exit(1);
    }
    else
    {
        printf("bind ok.\n");
        printf("local port : %d\n",LOCALPORT);
    }
    while(1)
    {
        bzero(msg,sizeof(msg));
        /*接收到的信息*/
        len=recvfrom(mysock,msg,sizeof(msg),0,&addr,&addr_len);
        printf("%d :",i);
        i++;
        printf("msg from: %s\n",inet_ntoa(addr.sin_addr));
        printf(" msg len: %d\n",len);
        printf(" msg: %s\n",msg);
        sendto(mysock,msg,len,0,&addr,addr_len);
        /*以上将字符串返回给客户端*/
    }
    return 0;
}


知识点补充:

套接字=传输层协议+端口号+IP地址

套接字相关类型:sockaddr或sockaddr_in

struct sockaddr//系统中定义好的
{
    unsigned short int sa_family;
    char sa_data[14];
};

sa_family:指定通信的地址类型。如果是TCP/IP通信,则为AF_INET

sa_data:最多14个字符长度,用来保存IP地址和端口信息

struct socketaddr_in
{
    unsigned short int sin_family;
    uint16_t sin_port;
    struct in_addr sin_addr;
    unsigned char sin_zero[8];
};
struct in addr
{
    uint32_t s_addr;//保存一个IP地址
};

sin_family和sa_family相同

sin_port:套接字使用的端口号

sin_addr:需要访问的IP地址

sin_zero:未使用的字段,填充为0


好的~接下来开始看代码(至于什么时候导入什么包需要另开blog记下来才可以!)

socket(AF_INET, SOCK_DGRAM, 0)创建socket并将返回号码到mysock,创建成功后,注意套接字放到addr中,bzero(&addr,sizeof(addr))-->bzero(void *s, int n)功能:置字节字符串s的前n个字节为零且包括‘\0’。建议改成memset()函数作初始化。初始化addr的各项参数,参考struct socketaddr_in;通过bind(mysock,&addr,sizeof(addr))绑定端口;然后就可以等待客户端给服务器端发送消息了~~

while循环一直等待客户端发送消息,recvfrom(mysock,msg,sizeof(msg),0,&addr,&addr_len)负责接收消息,接收的长度放到len中。inet_ntoa(addr.sin_addr)将一个IP转换成一个互联网标准点分格式的字符串,sendto(mysock,msg,len,0,&addr,addr_len)将字符串返回给客户端。


接下来是客户端的代码:

#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/socket.h>
#define REMOTEPORT 4567
#define REMOTEIP "127.0.0.1"
int main(int argc, char *argv[])
{
    int s,len;
    struct sockaddr_in addr;//套接字结构体
    int addr_len;
    char msg[256];
    int i = 0;
    if((s=socket(AF_INET, SOCK_DGRAM, 0)) < 0)
    {
        perror("error");
        exit(1);
    }
    else
    {
        printf("socket created.\n");
        printf("socket id:%d\n",s);
        printf("remote ip:%s\n",REMOTEIP);
        printf("remote port:%d\n",REMOTEPORT);
    }
    addr_len=sizeof(struct sockaddr_in);
    bzero(&addr, sizeof(addr));
    addr.sin_family=AF_INET;
    addr.sin_port=htons(REMOTEPORT);
    addr.sin_addr.s_addr=inet_addr(REMOTEIP);//struct in_addr sin_addr
    while(1)
    {
        bzero(msg,sizeof(msg));
        len = read(STDIN_FILENO, msg, sizeof(msg));
        /*s是建立好的socket,msg是发送的字符串,len是字符长度,flag=0*/
        sendto(s,msg,len,0,&addr,addr_len);
        printf("\nInput message: %s\n",msg);
        /*这是接受到的信息*/
        len = recvfrom(s,msg,sizeof(msg),0,&addr,&addr_len);
        printf("%d: ",i);
        i++;
        printf("Received message: %s\n",msg);/*这是服务器返回的信息*/
    }
    return 0;
}

解释一下和上面有差异和没解析的部分~

htonl:将计算机中的32位长整型数转换成网络字符顺序的32位长整型数

htons:(同上,16位)

ntohl:将网络字符顺序的32位长整型数转换成计算机中的32位长整型数

ntohs:(同上,16位)

read(STDIN_FILENO, msg,sizeof(msg));函数等待用户键盘输入