5.1.3 简单的 客户端 和服务端 程序实现代码

服务端

  1. 调用socket函数返回一个文件描述符sockfd

  2. 专用socket地址

  • UNIX 本地协议簇
    struct sockaddr_un

  • TCP/IP协议簇

struct sockaddr_in //IPV4
struct sockaddr_in6 //IPV6

struct sockaddr_in {
        short   sin_family;         //address family 协议簇
        u_short sin_port;           //16 bit TCP/UDP port number	端口号
        struct  in_addr sin_addr;   //32 bit IP address		网络字节序(IP地址转化后)
        char    sin_zero[8];        //not use, for align
};
  1. 给sockfd文件描述符 命名
    int bind(int sockfd, const struct sockaddr* my_addr ,socklen_t addrlen);
    将my_addr指向的socket地址

  2. 监听socket

int listen(int sockfd,int backlog); //backlog指最大监听队列长度
  1. 接收连接
int accept(int sockfd ,struct sockaddr *addr ,socklen_t *addrlen);

accept阻塞等待客户连接,返回新的套接字,该套接字可以和客户端通信write或read

客户端

  1. socket()创建sockfd文件描述符
    这里 专用socket地址 可以指定协议簇、目标服务器的端口号 和 目标服务器的网络字节序

  2. connect() //客户端操作

int connect(int sockfd ,const struct sockaddr *serv_addr ,socklen_t addrlen);

connect()函数将创建的文件描述符 和 专用的socket地址 连接 ,

  1. 读写操作

下面是客户端和服务端通信的例子

环境 linux
server.c

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

#define MAX_BUFFER 1024

int main(int argc, char const *argv[])
{
    if(argc <=2 ){
        printf("ip port error\n");
    }
    const char * ip =argv[1];
    int port =atoi(argv[2]);
    //创建socket 地址,绑定 服务器的ip 和端口
    struct sockaddr_in adderss;
    bzero(&adderss,sizeof(adderss));
    adderss.sin_family=AF_INET;
    inet_pton(AF_INET,ip,&adderss.sin_addr);
    adderss.sin_port=htons(port);
    //创建socket ,并 用bind 绑定socket地址(即给socket命名)
    int sock =socket(PF_INET,SOCK_STREAM,0);
    assert(sock>=0);
    int ret =bind(sock,(struct sockaddr*)&adderss,sizeof(adderss));
    assert(ret!=-1);
    //使用listen 创建监听队列,5 指的是完全连接的socket最大上限
    ret =listen(sock ,5);
    assert(ret>=0);
    //accept得到监听套接字,和监听套接字地址
    struct sockaddr_in connsock;
    socklen_t len_connsock = sizeof(connsock);
    int connfd = accept(sock ,(struct sockaddr*)&connsock ,&len_connsock);
    if(connfd <0){
        printf("error is %d\n",errno);
    }else{
        char buffer [MAX_BUFFER];
        memset(buffer ,'\0',MAX_BUFFER);

        printf("收到 %d 字节,内容为 %s\n",ret,buffer);

        ret =recv(connfd,buffer,MAX_BUFFER-1,0);//返回的ret是收到多少字节
        printf("收到 %d 字节,内容为 %s\n",ret,buffer);
        // close(connfd);  //主动断开连接 ,进入TIME_WAIT 状态
    }
    close(sock);
    return 0;
}

客户端
client.c

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


int main(int argc, char const *argv[])
{
    if(argc <=2) 
    {
        printf("ip or port is needed\n");
        return 1;
    }
    const char * ip =argv[1];
    int port =atoi(argv[2]);
    struct sockaddr_in address;
    bzero(&address,sizeof(address));
    address.sin_family =AF_INET;
    inet_pton(AF_INET,ip,&address.sin_addr);
    address.sin_port=htons(port);


    int sock =socket(PF_INET,SOCK_STREAM,0);
    assert(sock>=0);
    if(connect(sock,(struct sockaddr*)&address , sizeof(address))<0){
        printf("connect error\n");
    }else{
        char * data ="I am client ,hello server";
        send(sock,data,strlen(data),0);   
    }
    close(sock);
    return 0;
}
posted @ 2021-05-19 15:27  appearAndLeave  阅读(136)  评论(0)    收藏  举报