套接字概述

在Linux中,一切都是文件. Linux 中的网络编程通过socket接口进行,   socket是一种特殊的I/0接口, 也是一种文件描述符. 常用的进程之间通信.   下图是使用TCP协议的通信过程 :

linux网络编程

 

三次握手建立连接

linux网络编程

 

 

 

四次挥手断开连接

 linux网络编程

 

这里通过实现两个例子了解一些常用API的用法, 不废话, 直接上代码.

 

1.回声客户端

服务端代码

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<pthread.h>
#include<unistd.h>
#include<errno.h>
#include<netdb.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<sys/types.h>

#define            PORT                4321        //端口号
#define            BUFFER_SIZE            1024        //缓冲区大小    
#define            MAX_QUE_CONN_NM        5            //最大请求队列

/* 处理客户端请求 */
void *conn_hand(void *arg){
    
    int client_fd = *(int *)arg;
    int recvbytes, sendbytes;
    char buf_recv[BUFFER_SIZE] = {0}, buf_send[BUFFER_SIZE];

    while(1){
    
        /* 调用recv()函数, 接受客户端请求. 从缓冲区中读取. */
        if((recvbytes = recv(client_fd, buf_recv, BUFFER_SIZE, 0)) == -1){
            perror("recv");
            break;
        }
        printf("receive from client: %s\n", buf_recv);

        /* 退出 */
        if(strcmp(buf_recv, "quit") == 0) break;

        /* 向客户端发送数据  这里只是写入缓冲区, 由TCP协议发送至网络中*/
        if(send(client_fd, buf_recv, recvbytes, 0) == -1){
            perror("send");
            break;
        }
        memset(buf_recv, 0, BUFFER_SIZE);

    }
    printf("terminating current connect...\n");
    close(client_fd);
    pthread_exit(NULL);
}

int main(void){

    struct sockaddr_in server_sockaddr, client_sockaddr;
    int sin_size;
    int sockfd, client_fd;

    /* 建立socket连接 */
    if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){
        perror("socket");
        exit(1);
    }
    printf("socket id=%d\n", sockfd);
    
    /* 设置sockaddr_in 结构体参数 */
    server_sockaddr.sin_family = AF_INET;
    server_sockaddr.sin_port = htons(PORT);
    server_sockaddr.sin_addr.s_addr = INADDR_ANY;
    bzero(&(server_sockaddr.sin_zero),8) ;

    /* 允许重复本地址绑定套接字 */
    int i = 1;
    setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i));

    /* 绑定函数bind() */
    if(bind(sockfd, (struct sockaddr *)&server_sockaddr, sizeof(struct sockaddr)) == -1){
        perror("bind");
        exit(1);
    }
    printf("bind success!\n");
    
    /* 调用listen函数监听, 创建未处理请求队列 */
    if(listen(sockfd, MAX_QUE_CONN_NM) == -1){
        perror("listen");
        exit(1);
    }
    printf("listening port:%d ...\n", PORT);
   
    sin_size = sizeof(client_sockaddr);
    /* 循环接收客户端请求 */
    while(1){
        pthread_t tid;

        client_fd = accept(sockfd, (struct sockaddr *)&client_sockaddr, &sin_size);
        
        /* 创建新线程处理客户端请求*/
        if(pthread_create(&tid, NULL, conn_hand, &client_fd) == -1){
            perror("pthread_create");
            break;
        }
    }
    close(sockfd);
    exit(0);
}
View Code  

相关文章:

猜你喜欢
  • 2022-12-23
  • 2021-11-02
  • 2021-09-20
  • 2021-07-27
  • 2021-10-03
相关资源
相似解决方案