欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Linux下socket通信示例

程序员文章站 2022-06-29 22:49:18
...

服务端socket流程:socket() –> bind() –> listen() –> accept() –> 读取、发送信息(recv,send等)

客户端socket流程:socket() –> connect() –> 发送、读取信息(send,recv等)

参考:Socket基本操作

最基础版本

服务端监听某个端口,客户端连接之后发送数据——>客户端断开连接后,服务端也关闭了

服务端:

#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>

const int Port = 8888;

int main(void){
    int sock_fd;
    struct sockaddr_in mysock;
    sock_fd = socket(AF_INET,SOCK_STREAM,0);//初始化socket

    memset(&mysock,0,sizeof(mysock));

    //编辑地址信息
    mysock.sin_family = AF_INET;
    mysock.sin_port = htons(Port);
    mysock.sin_addr.s_addr = INADDR_ANY;

    bind(sock_fd,(struct sockaddr *)&mysock,sizeof(struct sockaddr));//绑定地址,然后监听
    if(listen(sock_fd,10) < -1){
        printf("listen error.\n");
    }

    int sin_size = sizeof(struct sockaddr_in);
    struct sockaddr_in client_addr;
    int new_fd;
    char buf[1024];
    char sedbuf[1024] = "recv successfully.\n";

    printf("listening...\n");
    new_fd = accept(sock_fd, (struct sockaddr *)&client_addr, &sin_size);//accpet
    while(1){
        int len = recv(new_fd,buf,sizeof(buf),0);
        fputs(buf,stdout);
        send(new_fd, sedbuf, sizeof(sedbuf), 0);
        if(strcmp(buf,"exit\n") == 0){
            break;
        }
        memset(buf,0,sizeof(buf));
    }
    close(new_fd);
    close(sock_fd);
    return 0;

客户端:

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

const int Port = 8888;

int main(void){
    int sock_fd;
    char buf[1024], sendbuf[1024], recvbuf[1024];
    struct sockaddr_in server_addr;
    sock_fd = socket(AF_INET, SOCK_STREAM, 0);//初始化socket
    if(sock_fd == -1){
        printf("%s\n",strerror(errno));
        return 0;
    }

    bzero(&server_addr, sizeof(server_addr));//编辑服务端地址信息
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(Port);
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);

    int tmp = connect(sock_fd, (struct sockaddr *)(&server_addr), 
        sizeof(struct sockaddr));//连接服务端socket
    if(tmp == -1){
        printf("%s\n",strerror(errno));
        return 0;
    }

    while(1){
        fgets(sendbuf, sizeof(sendbuf), stdin);
        send(sock_fd, sendbuf, strlen(sendbuf), 0);
        if(strcmp(sendbuf, "exit\n") == 0)
            break;
        recv(sock_fd, recvbuf, sizeof(recvbuf), 0);
        fputs(recvbuf, stdout);
        memset(sendbuf, 0, sizeof(sendbuf));
        memset(recvbuf, 0, sizeof(recvbuf));
    }
    close(sock_fd);
    return;
}

多客户端与服务端通信

只需在服务端修改,增加多线程,就可以同时接收多个客户端发送的信息了。

服务端:

#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <pthread.h>

const int Port = 8888;
pthread_mutex_t g_mutext;

struct pthread_data{
    struct sockaddr_in client_addr;//客户端的地址信息
    int sock_fd;//与客户端通信的Socket文件描述符
};

void serveForClient(void * arg);

int main(void){
    int sock_fd;
    struct sockaddr_in mysock;
    struct pthread_data pdata;
    pthread_t pt;

    sock_fd = socket(AF_INET,SOCK_STREAM,0);//初始化socket

    //编辑地址信息
    memset(&mysock,0,sizeof(mysock));
    mysock.sin_family = AF_INET;
    mysock.sin_port = htons(Port);
    mysock.sin_addr.s_addr = INADDR_ANY;

    bind(sock_fd,(struct sockaddr *)&mysock,sizeof(struct sockaddr));//绑定地址,然后监听
    if(listen(sock_fd,10) < -1){
        printf("listen error.\n");
    }

    int sin_size = sizeof(struct sockaddr_in);
    struct sockaddr_in client_addr;
    int new_fd;

    printf("listening...\n");
    while(1){
        new_fd = accept(sock_fd, (struct sockaddr *)&client_addr, &sin_size);//accpet

        //将client信息和Socket文件描述符打包进结构体中,传给线程
        pdata.client_addr = client_addr;
        pdata.sock_fd = new_fd;
        pthread_create(&pt, NULL, serveForClient, (void *)&pdata);//新开一个线程,与这个连接进来的client通信
    }
    close(new_fd);
    close(sock_fd);
    return 0;
}

void serveForClient(void *arg){
    struct pthread_data *pdata = (struct pthread_data*)arg;
    int new_fd = pdata->sock_fd;
    char recvbuf[1024];
    char sendbuf[1024] = "recv successfully.\n";
    while(1){
        recv(new_fd,recvbuf,sizeof(recvbuf),0);
        fputs(recvbuf,stdout);
        strcpy(sendbuf, recvbuf);
        send(new_fd, sendbuf, sizeof(sendbuf), 0);
        if(strcmp(recvbuf,"exit\n") == 0){
            break;
        }
        memset(recvbuf,0,sizeof(recvbuf));
    }
    return;
}