裸奔 的傻瓜
在通往Ac的路上 蹒跚踱步
1)第一个就是头文件的添加
#include <errno.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <unistd.h>
#include <arpa/inet.h>

大体上面几个头文件就可以完成一次基本的客户端服务器交互了。具体每个头文件的重要还不是很清晰,但是可以通过查询得知。
特别就是<errno.h>中的错误处理函数 挺好用的 但是还是要不是很了解。。

2)数据类型
    struct sockaddr
    {
       unsigned short  sa_family;   //地址族, 一般为AF_INET
       char                  sa_data[14];   //14字节的协议地址
    }

    struct sockaddr_in
    {
       short int                     sin_family;   //地址族
       unsigned short int      sin_port;      //端口号
       struct in_addr             in_addr;      //ip地址
       unsigned char             sin_zero[8];  //填充
    }

通常所定义 sockaddr_in 然后再转换成sockaddr进行地址传输

几个函数
·htonl():把32位值从主机字节序转换成网络字节序
·htons():把16位值从主机字节序转换成网络字节序
·ntohl():把32位值从网络字节序转换成主机字节序
·ntohs():把16位值从网络字节序转换成主机字节序

至于ip地址转换
inet_addr("127.0.0.1");
还有一个就是通过主机地址来解析的
gethostbyname 具体怎么用 可以去查下

然后自己感觉 ip转换函数都是在
inet_XX后面的。。。

典型的定义本机地址。。。
    my_addr.sin_family=AF_INET;
    my_addr.sin_port=htons(8000);
    //my_addr.sin_addr.s_addr=inet_addr("127.0.0.1");
    my_addr.sin_addr.s_addr=INADDR_ANY;

3)常用函数
   1 socket()
       头文件:
       #include <sys/types.h>
       #include <sys/socket.h>
       函数原型:
       int socket(int domain, int type, int protocol)
          domain: 协议类型,一般为AF_INET
          type: socket类型
          protocol:用来指定socket所使用的传输协议编号,通常设为0即可

注释:
    (1)常用的Socket类型有两种:流式Socket(SOCK_STREAM)和数据报式Socket(SOCK_DGRAM)。流式是一种面向连接的 Socket,针对于面向连接的TCP服务应用;数据报式Socket是一种无连接的Socket,对应于无连接的UDP服务应用
    (2)协议类型 AF_INET PF_INET 貌似没有什么区别
    AF 表示ADDRESS FAMILY就是地址族
    PF 表示PROTOCL FAMILY就是协议族

    2 bind()
       头文件:
       #include <sys/types.h>
       #include <sys/socket.h>
       函数原型:
       int bind(int sockfd, struct sockaddr *my_addr, int addrlen)
          sockfd: socket描述符
          my_addr:是一个指向包含有本机ip地址和端口号等信息的sockaddr类型的指针
          addrlen:常被设为sizeof(struct sockaddr)
注释:
    更加普遍的使用方式是:
    int socketID;
    struct sockaddr_in my_addr;
    //...    
    bind(socketID,(struct sockaddr*)&my_addr,sizeof(struct sockaddr));

    3 connect()
       头文件:
       #include <sys/types.h>
       #include <sys/socket.h>
       函数原型:
       int connect(int sockfd, struct sockaddr *serv_addr, int addrlen)
           sockfd: 目的服务器的socket描述符
           serv_addr:包含目的机器ip地址和端口号的指针
           addrlen:sizeof(struct sockaddr)
注释:
    貌似addrlen 可以用 socklen_t 类型。但是用int 也是没有问题的

    4 listen()
       头文件:
       #include <sys/socket.h>
       函数原型:
       int listen(int sockfd, int backlog);
           sockfd:socket()系统调用返回的socket描述符
           backlog:指定在请求队列中的最大请求数,进入的连接请求将在队列中等待accept()它们。

    5 accept()
       头文件:  
       #include <sys/types.h>
       #inlcude <sys/socket.h>
       函数原型:
       int accept(int sockfd, void *addr, int addrlen)
           sockfd:是被监听的socket描述符
           addr:通常是一个指向sockaddr_in变量的指针,该变量用来存放提出连接请求服务的主机的信息
           addrlen:sizeof(struct sockaddr_in)

注释:
    这里我觉得很有问题,因为我在编译的时候使用的下面的构造
    struct sockaddr_in client_addr;
    socklen_t size=sizeof(struct sockaddr);
    client=accept(socketID,(struct sockaddr*)&client_addr,&size);
    而使用上面的构造的时候:
    编译的时候就会出错。。。
      

    6 send()
        头文件:
        #include <sys/socket.h>
        函数原型:
        int send(int sockfd, const void *msg, int len, int flags);
           sockfd:用来传输数据的socket描述符
           msg:要发送数据的指针
           flags: 0
     
    7 recv()
        头文件:
        #include <sys/types.h>
        #include <sys/socket.h>
        函数原型:
        int recv(int sockfd, void *buf, int len, unsigned int flags)
          sockfd:接收数据的socket描述符
          buf:存放数据的缓冲区
          len:缓冲的长度
          flags:0

    8 sendto()
       头文件:
       #include <sys/types.h>
       #include <sys/socket.h>
       函数原型:
       int sendto(int sockfd, const void *msg, int len, unsigned int flags, const struct sockaddr *to, int tolen);
       
   
    9 recvfrom()
       头文件:
       #include <sys/types.h>
       #include <sys/socket.h>
       函数原型:
       int recvfrom(int sockfd, void *buf, int len, unsigned int flags, struct sockaddr *from, int fromlen)

   
    10 read() write()
       int read(int fd, char *buf, int len)
       int write(int fd, char *buf, int len)
      
    11 shutdown()
       close(sockfd)
       int shutdown(int sockfd, int how)

4)代码

服务器端:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <unistd.h>
#include <arpa/inet.h>

int main()
{
    struct sockaddr_in my_addr;
    
    int socketID=socket(AF_INET,SOCK_STREAM,0);

    my_addr.sin_family=AF_INET;
    my_addr.sin_port=htons(8000);
    //my_addr.sin_addr.s_addr=inet_addr("127.0.0.1");
    my_addr.sin_addr.s_addr=INADDR_ANY;    
    
    bind(socketID,(struct sockaddr*)(&my_addr),sizeof(struct sockaddr));
            
    printf("Wait For being connected!"n");

    int client;
    listen(socketID,20);    

    struct sockaddr_in client_addr;
    socklen_t size=sizeof(struct sockaddr);
    client=accept(socketID,(struct sockaddr*)&client_addr,&size);
    
    printf("ONE Connect!"n");
        
    char *msg="Hello";
    int len =strlen(msg);
    
    printf("%d"n",len);

    int suc=send(client,msg,len,0);

    if(suc<0)
        printf("MSG send error!,Error Marker is %d, Error msg is%s "n",errno,strerror(errno));
    else
        printf("MSG Send"n");

    return 0;
}

客户端:
#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>

int main()
{
    struct sockaddr_in server_addr;

    int socketID;
    socketID=socket(AF_INET,SOCK_STREAM,0);
    
    server_addr.sin_family=AF_INET;
    server_addr.sin_port=htons(8000);
    server_addr.sin_addr.s_addr=inet_addr("127.0.0.1");

    int size=sizeof(struct sockaddr);
    if(connect(socketID,(struct sockaddr*)&server_addr,size)<0)
        printf("Connetct error!"n");
    else
        printf("Connect successed!"n");    

    char msg[30];
    recv(socketID,msg,30,0);
    
    int msgLen=strlen(msg);
    printf("%d"n",msgLen);

    printf("%s"n",msg);

    char ss[]="1230faflg";
    
    if(send(socketID,ss,10,0)<0) printf("Send Error!"n");

    return 0;
}

代码实现的功能很少,主要就是测试一下linux下的网络连接函数怎么用才行。
模型都是很简单的 但是用起来是需要功力的


PS:大部分的内容都是来源网络,最近才开始使用linux平台。整理了下内容,加深下自己的理解。
posted on 2009-05-23 15:03  Lyt  阅读(1553)  评论(0编辑  收藏  举报