Linux下socket通信示例

服務端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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章