C语言实现Linux下,基于TCP与UDP协议,不同进程下单线程通信服务器
 
一、TCP单线程通信服务器
 
- 先运行server端,再运行client端
 - 输入"exit" 是退出
 
 
1.1 server_TCP.c
 
**#include <my_head.h>
#define PORT 6666
#define IP "192.168.125.103"
int main(int argc, const char *argv[])
{
    
    int server_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (server_fd < 0)
    {
        ERR_MSG("socket");
        return -1;
    }
    printf("套接字创建成功 server_fd = %d\n", server_fd);
    
    int reuse = 1;
    if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0)
    {
        ERR_MSG("setsockopt");
        return -1;
    }
    printf("允许端口快速复用成功\n");
    
    struct sockaddr_in server_in;              
    server_in.sin_family = AF_INET;            
                                               
    server_in.sin_port = htons(PORT);          
    server_in.sin_addr.s_addr = inet_addr(IP); 
    if (bind(server_fd, (struct sockaddr *)&server_in, sizeof(server_in)) < 0)
    {
        ERR_MSG("bin");
        return -1;
    }
    printf("bind 成功\n");
    
    if (listen(server_fd, 256) < 0)
    {
        ERR_MSG("listen");
        return -1;
    }
    printf("listen 成功\n");
    
    
    struct sockaddr_in client_in;                                             
    socklen_t addrlen = sizeof(client_in);                                    
    int new_fd = accept(server_fd, (struct sockaddr *)&client_in, &addrlen); 
    if (new_fd < 0)
    {
        ERR_MSG("accept");
        return -1;
    }
    printf("new_fd = %d    __%d__\n", new_fd, __LINE__);
    
    printf("client IP = %s\n", inet_ntoa(client_in.sin_addr));
    printf("client port = %d\n", ntohs(client_in.sin_port));
    
    char buff[128];
    ssize_t res = 0;
    while (1)
    {
        
        bzero(buff, sizeof(buff));
        
        
        res = read(new_fd, buff, sizeof(buff));
        if (res < 0)
        {
            ERR_MSG("recv");
            return -1;
        }
        
        else if (0 == res)
        {
            printf("[ %s : %d ]客户端断开链接\n", inet_ntoa(client_in.sin_addr),
                   ntohs(client_in.sin_port));
            break;
        }
        
        printf("[ %s : %d ] [massage : %s ]\n", inet_ntoa(client_in.sin_addr),
               ntohs(client_in.sin_port), buff);
        
        if (!strcmp(buff, "exit"))
        {
            printf("已断开\n");
            break;
        }
        
        
        printf("回复:");
        scanf("%s", buff);
        if (!strcmp(buff, "exit"))
        {
            printf("已断开\n");
            break;
        }
        
        if (send(new_fd, buff, sizeof(buff), 0) < 0)
        {
            ERR_MSG("send");
            return -1;
        }
        printf("buff = %s\n", buff);
        putchar(10);
    }
    
    close(server_fd);
    close(new_fd);
    return 0;
}
 
1.2 client_TCP.c
 
#include <my_head.h>
#define SERVER_PORT 6666            
#define SERVER_IP "192.168.125.103" 
int main(int argc, const char *argv[])
{
    
    int client_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (client_fd < 0)
    {
        ERR_MSG("socket");
        return -1;
    }
    printf("套接字创建成功 client_fd = %d\n", client_fd);
    
    int reuse = 1;
    if (setsockopt(client_fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0)
    {
        ERR_MSG("setsockopt");
        return -1;
    }
    printf("允许端口快速复用成功\n");
    
    
    
    struct sockaddr_in server_in;
    server_in.sin_addr.s_addr = inet_addr(SERVER_IP);
    server_in.sin_port = htons(SERVER_PORT);
    server_in.sin_family = AF_INET;
    
    if (connect(client_fd, (struct sockaddr *)&server_in, sizeof(server_in)) < 0)
    {
        ERR_MSG("connect");
        return -1;
    }
    char buff[128];
    ssize_t res = 0;
    while (1)
    {
        
        printf("请输入 : ");
        fgets(buff, sizeof(buff), stdin);
        buff[strlen(buff) - 1] = 0;
        if (send(client_fd, buff, sizeof(buff), 0) < 0)
        {
            ERR_MSG("send");
            return -1;
        }
        if (!strcmp(buff, "exit"))
        {
            printf("断开链接\n");
            break;
        }
        printf("发送成功\n");
        bzero(buff, sizeof(buff));
        
        res = recv(client_fd, buff, sizeof(buff), 0);
        if (res < 0)
        {
            ERR_MSG("recv");
            return -1;
        }
        else if (0 == res)
        {
            printf("[ %s : %d ] 服务器断开链接   __%d__\n", SERVER_IP, SERVER_PORT, __LINE__);
            break;
        }
        printf("[ %s : %d ] [massage : %s ]\n", SERVER_IP, SERVER_PORT, buff);
    }
    close(client_fd);
    return 0;
}
 
二、TCP单线程通信服务器
 
- 先运行server端,再运行client端
 - 输入"exit" 是退出
 
 
2.1 server_UDP.c
 
#include <my_head.h>
#define SERVER_PORT 6666
#define SERVER_IP "192.168.125.103"
int main(int argc, const char *argv[])
{
    
    int client_fd = socket(AF_INET, SOCK_DGRAM, 0);
    if (client_fd < 0)
    {
        ERR_MSG("socket");
        return -1;
    }
    printf("套接字创建成功 client_fd = %d\n", client_fd);
    
    int reuse = 1;
    if (setsockopt(client_fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0)
    {
        ERR_MSG("setsockopt");
        return -1;
    }
    printf("允许端口快速复用成功\n");
    
    
    
    struct sockaddr_in server_addr;                     
    server_addr.sin_family = AF_INET;                   
                                                        
    server_addr.sin_port = htons(SERVER_PORT);          
    server_addr.sin_addr.s_addr = inet_addr(SERVER_IP); 
    
    char buff[128];
    ssize_t res = 0;
    struct sockaddr_in client_addr;
    socklen_t client_len = sizeof(client_addr);
    while (1)
    {
        
        bzero(buff, sizeof(buff));
        
        
        printf("请输入 : ");
        scanf("%s", buff);
        
        
        if (sendto(client_fd, buff, sizeof(buff), 0, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0)
        {
            ERR_MSG("sendto");
            return -1;
        }
        if (!strcmp(buff, "exit"))
        {
            printf("已断开\n");
            break;
        }
        printf("buff = %s\n", buff);
        
        
        
        res = recvfrom(client_fd, buff, sizeof(buff), 0, (struct sockaddr *)&client_addr, &client_len);
        if (res < 0)
        {
            ERR_MSG("recv");
            return -1;
        }
        
        printf("[ %s : %d ] [massage : %s ]\n", inet_ntoa(client_addr.sin_addr),
               htons(client_addr.sin_port), buff);
        
        if (!strcmp(buff, "exit"))
        {
            printf("已断开\n");
            break;
        }
        putchar(10);
    }
    
    close(client_fd);
    return 0;
}
 
2.2 client_UDP.c
 
#include <my_head.h>
#define PORT 6666
#define IP "192.168.125.103"
int main(int argc, const char *argv[])
{
    
    int server_fd = socket(AF_INET, SOCK_DGRAM, 0);
    if (server_fd < 0)
    {
        ERR_MSG("socket");
        return -1;
    }
    printf("套接字创建成功 server_fd = %d\n", server_fd);
    
    int reuse = 1;
    if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0)
    {
        ERR_MSG("setsockopt");
        return -1;
    }
    printf("允许端口快速复用成功\n");
    
    struct sockaddr_in server_in;              
    server_in.sin_family = AF_INET;            
                                               
    server_in.sin_port = htons(PORT);          
    server_in.sin_addr.s_addr = inet_addr(IP); 
    
    if (bind(server_fd, (struct sockaddr *)&server_in, sizeof(server_in)) < 0)
    {
        ERR_MSG("bind");
        return -1;
    }
    printf("bind 成功\n");
    
    
    char buff[128];
    ssize_t res = 0;
    struct sockaddr_in client_addr;
    socklen_t client_len = sizeof(client_addr);
    while (1)
    {
        
        bzero(buff, sizeof(buff));
        
        
        
        res = recvfrom(server_fd, buff, sizeof(buff), 0, (struct sockaddr *)&client_addr, &client_len);
        if (res < 0)
        {
            ERR_MSG("recvfrom");
            return -1;
        }
        
        printf("[ %s : %d ] [massage : %s ]\n", inet_ntoa(client_addr.sin_addr),
               htons(client_addr.sin_port), buff);
        
        if (!strcmp(buff, "exit"))
        {
            printf("已断开\n");
            break;
        }
        
        
        printf("回复:");
        scanf("%s", buff);
        if (!strcmp(buff, "exit"))
        {
            printf("已断开\n");
            break;
        }
        
        if (sendto(server_fd, buff, sizeof(buff), 0, (struct sockaddr *)&client_addr, client_len) < 0)
        {
            ERR_MSG("sendto");
            return -1;
        }
        printf("buff = %s\n", buff);
        putchar(10);
    }
    
    close(server_fd);
    return 0;
}