socket

来源:互联网 发布:帝国cms图片替换地址 编辑:程序博客网 时间:2024/05/17 20:34

1.socket是一个常用的网络通信API,今天就学习一下多线程配合socket进行通信。

服务端server.c

#include <stdio.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <string.h>#include <pthread.h>#include <unistd.h>#define SERVERPORT     9009#define BACKLOG     10#define HI "success!\n"#define END "end"static int server_fd = -1, client_fd = -1;static void *create_server(void){    int ret = -1;    struct sockaddr_in server_addr = {0}, client_addr = {0};    socklen_t sock_len = 0;    char recv_buf[128] = {0};    server_fd = socket(AF_INET, SOCK_STREAM, 0);  //创建socket句柄    if(server_fd < 0)    {        perror("socket");        return NULL;    }    server_addr.sin_family = AF_INET;            //设置ipv4协议    server_addr.sin_port = htons(SERVERPORT);    //设置端口    server_addr.sin_addr.s_addr = INADDR_ANY;    //设置ip地址为本机地址    ret = bind(server_fd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr_in));  //绑定地址    if(ret == -1)    {        perror("server bind");        return NULL;    }    ret = listen(server_fd, BACKLOG);         //监听地址    if (ret < 0)    {        perror("listen");        return NULL;    }    client_fd = accept(server_fd, (struct sockaddr *)&client_addr, &sock_len);  //等待服务端连接    printf("client connected, fd = %d\n", client_fd);    while(1)    {        ret = send(client_fd, HI, sizeof(HI), 0);                //发送success给客户端        printf("send to client msg length = %d\n", ret);        ret = recv(client_fd, &recv_buf, sizeof(recv_buf), 0);   //接收客户端传递的消息        printf("recv from client msg: %s\n", recv_buf);        if(strncmp(END, recv_buf, sizeof(END)) == 0)             //接收到end,结束通信        {            ret = send(client_fd, recv_buf, strlen(recv_buf), 0);            printf("server exited, send last msg to client length = %d\n",ret);            return NULL;        }        memset(recv_buf, 0, sizeof(recv_buf));    }    return NULL;}int main(int argc, char const *argv[]){    int ret = -1;    pthread_t pt = -1;    ret = pthread_create(&pt, NULL, (void *)create_server, NULL);  //创建子线程    if(ret != 0)    {        perror("pthread_create");        goto out;    }    ret = pthread_join(pt, NULL);     //等待线程结束    if(ret != 0)    {        perror("pthread_join");    }out:    if(server_fd != -1) close(server_fd);    //释放资源    if(client_fd != -1) close(client_fd);    return 0;}

客户端client.c

#include <stdio.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <string.h>#include <pthread.h>#include <unistd.h>#define SERVERPORT     9009#define END "end"static int client_fd = -1;static int init(void){    int ret = -1;    struct sockaddr_in client_addr = {0};    client_fd = socket(AF_INET, SOCK_STREAM, 0);   //创建socket句柄    if(client_fd < 0)    {        perror("socket");        return -1;    }    client_addr.sin_family = AF_INET;            //和服务端一毛一样    client_addr.sin_port = htons(SERVERPORT);    client_addr.sin_addr.s_addr = INADDR_ANY;    ret = connect(client_fd, (struct sockaddr *)&client_addr, sizeof(struct sockaddr_in));  //连接到服务端    if(ret == -1)    {        perror("connect");        return -1;    }    return 0;}static void *recv_thread(void){    int ret = -1;    char recv_buf[128] = {0};    while(1)    {        ret = recv(client_fd, &recv_buf, sizeof(recv_buf), 0);   //接收服务端发过来的success信息        printf("recv from server: %s\n", recv_buf);        if(strncmp(END, recv_buf, sizeof(END)) == 0)      //收到end结束子线程        {            printf("client exited!\n");            return NULL;        }        memset(recv_buf, 0, sizeof(recv_buf));    }    return NULL;}static void *intput_thread(void){    char input_buf[128] = {0};    int ret = -1;    while(1)    {        scanf("%s", input_buf);          //键盘输入        ret = send(client_fd, input_buf, strlen(input_buf), 0);  //发送键盘输入的信息        printf("intput_thread send to server msg length = %d\n", ret);        if(strncmp(END, input_buf, sizeof(END)) == 0)    //输入end结束子线程        {            printf("intput_thread exited!\n");            return NULL;        }        memset(input_buf, 0, sizeof(input_buf));    }    return NULL;}int main(int argc, char const *argv[]){    int ret = -1;    pthread_t pt1 = -1, pt2 = -1;    if(init())    {        return -1;    }    ret = pthread_create(&pt1, NULL, (void *)recv_thread, NULL);    if(ret != 0)    {        perror("pthread_create");        goto out;    }    ret = pthread_create(&pt2, NULL, (void *)intput_thread, NULL);    if(ret != 0)    {        perror("pthread_create");        goto out;    }    ret = pthread_join(pt1, NULL);    if(ret != 0)    {        perror("pthread_join pt1");    }    ret = pthread_join(pt2, NULL);    if(ret != 0)    {        perror("pthread_join pt2");    }out:    if(client_fd != -1) close(client_fd);    return 0;}

简单Makefile进行编译

all:gcc client.c -o client -pthreadgcc server.c -o server -pthread

原创粉丝点击