调用socket函数返回一个文件描述符sockfd
专用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
};
给sockfd文件描述符 命名
int bind(int sockfd, const struct sockaddr* my_addr ,socklen_t addrlen);
将my_addr指向的socket地址
监听socket
int listen(int sockfd,int backlog); //backlog指最大监听队列长度
int accept(int sockfd ,struct sockaddr *addr ,socklen_t *addrlen);
accept阻塞等待客户连接,返回新的套接字,该套接字可以和客户端通信write或read
socket()创建sockfd文件描述符
这里 专用socket地址 可以指定协议簇、目标服务器的端口号 和 目标服务器的网络字节序
connect() //客户端操作
int connect(int sockfd ,const struct sockaddr *serv_addr ,socklen_t addrlen);
connect()函数将创建的文件描述符 和 专用的socket地址 连接 ,
环境 linux
server.c
#include <stdio.h>
#include <ctype.h>
#include <unistd.h>
#include <sys/types.h>
#include <arpa/inet.h>  //struct  sockaddr_in 
#include <sys/socket.h>
#include <stdlib.h>
#include <string.h>
#define SERV_PORT 9000
int main(int argc , char *const * argv){
    int listenfd  = socket(AF_INET,SOCK_STREAM,0);  //参数(2,2,0)  listenfd是文件
    struct  sockaddr_in serv_addr;
    memset(&serv_addr,0,sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port= htons(SERV_PORT);  //端口号
    serv_addr.sin_addr.s_addr =htonl(INADDR_ANY);
    bind(listenfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)); //套接字和结构体sockaddr_in 进行绑定
    listen(listenfd,32); //请求数不超过32 
    int connfd;
    const char * pcontent = "I sent sth to client";
    for(;;){
        connfd =accept(listenfd,(struct sockaddr *)NULL ,NULL); //阻塞等待客户端连接 accept返回的是客户端套接字,往这个套接字写东西可以和客户端通信
        write(connfd ,pcontent ,strlen(pcontent));
        close(connfd);//关闭后等待下一个客户端连接 
    }
    close(listenfd);
    return 0;
}
客户端
client.c
#include <stdio.h>
#include <ctype.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h> //socket 函数
#include <arpa/inet.h> //sockaddr_in
#define SERV_PORT 9000
int main(int argc ,char *const *argv){
    int sockfd = socket(AF_INET ,SOCK_STREAM,0);
    struct sockaddr_in serv_addr;
    memset(&serv_addr,0,sizeof(serv_addr));
    serv_addr.sin_family = AF_INET; //选择协议簇 IPV4    
    serv_addr.sin_port = htons(SERV_PORT); //端口
    if(inet_pton(AF_INET,"192.168.1.126",&serv_addr.sin_addr) <=0){
        printf("调用inet_pton()失败,退出\n");
        exit(1);
    }
    if(connect(sockfd ,(struct sockaddr *)&serv_addr ,sizeof(serv_addr)) <0){
        printf("调用connect()函数失败,退出\n");
        exit(1);
    }
    int n;
    char recvline[1000+1];
    while( (  n = read(sockfd ,recvline ,1000) ) >0){ //  不是 == 判断 ,而是赋值 =
        recvline[n] =0;
        printf("收到的内容:%s\n",recvline);
    }
    close(sockfd);
    printf("程序执行完毕,退出 \n");
    return 0;
}

效果
开启两个bash

原文:https://www.cnblogs.com/appearAndLeave/p/14785282.html