一个简单的socket编程示例

1、服务端代码

#include <sys/stat.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <error.h>
#include <unistd.h>

#include <netdb.h>

#define SERVER_PORT     9000
#define SERVER_ADDR     "0.0.0.0"
#define MAX_LISTEN_NUM  20
#define MAX_MESSAGE_NUM 1024

int main(void)
{
    int server_sock, client_sock;

    struct sockaddr_in server_addr;
    struct sockaddr_in client_addr;
    
    char recv_msg[MAX_MESSAGE_NUM] = {0};

    int recv_data_num, addr_len, reuse;

    /* int socket(int domain, int type, int protocol) */
    server_sock = socket(AF_INET, SOCK_STREAM, 0);

    if (server_sock < 0)
    {
        perror("creat socket fail");

        return -1;
    }

    //设置套接字的属性使它能够在计算机重启的时候可以再次使用套接字的端口和IP
    reuse = 1;
    setsockopt(server_sock, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));

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

    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(SERVER_PORT);
    server_addr.sin_addr.s_addr = inet_addr(SERVER_ADDR);

    addr_len = sizeof(server_addr);

    /* int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) */
    if (bind(server_sock, (struct sockaddr *)&server_addr, addr_len))
    {
        perror("bind fail");

        return -1;
    }

    /* int listen(int sockfd, int backlog) */
    if (listen(server_sock, MAX_LISTEN_NUM) < 0)
    {
        perror("listen fail");

        return -1;
    }

    printf("server ip: %s, listening port: %d\n", SERVER_ADDR, SERVER_PORT);

    while (1)
    {
        printf("start accept client...\n");
        
        /* int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) */
        /* accep默认会阻塞进程,直到接收到client的连接请求并返回一个新的socket */
        client_sock = accept(server_sock, (struct sockaddr *)&client_addr, (socklen_t*)&addr_len);

        if (client_sock < 0)
        {
            perror("accept fail");

            continue;
        }

        printf("accept client connect success!!\n");
        printf("client ip: %s, port is %d\n", inet_ntoa(client_addr.sin_addr), htons(client_addr.sin_port));

        while (1)
        {
            recv_data_num = recv(client_sock, (void *)recv_msg, MAX_MESSAGE_NUM, 0);
            
            if (recv_data_num < 0)
            {
                perror("read fail");
                
                continue;
            }

            recv_msg[recv_data_num] = '\0';

            printf("server get client[%s] msg :%s\n", inet_ntoa(client_addr.sin_addr), recv_msg);
            
            /* 输入“exit”时退出进程 */
            if (strcmp("exit", recv_msg) == 0)
            {
                break;
            }
        }
    }

    close(server_sock);

    return 0;
}

2、客户端代码

#include <sys/stat.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <error.h>
#include <unistd.h>

#include <netdb.h>

#define MAX_MESSAGE_NUM 1024
#define SERVER_ADDR     "127.0.0.1"
#define SERVER_PORT     9000

int main()
{
    int client_sock;

    char send_msg[MAX_MESSAGE_NUM];

    struct sockaddr_in server_addr;

    int addr_len;
    

    client_sock = socket(AF_INET, SOCK_STREAM, 0);

    if (client_sock < 0)
    {
        perror("accept fail");

        return -1;
    }

    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = inet_addr(SERVER_ADDR);
    server_addr.sin_port = htons(SERVER_PORT);

    /* int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) */
    if (connect(client_sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0)
    {
        perror("connect fail");

        return -1;
    }

    printf("send message:\n");

    while (1)

    {
        scanf("%s", send_msg);

        send(client_sock, (void *)send_msg, strlen(send_msg), 0);

        /* 当接收到“exit”时退出 */
        if (strcmp("exit", send_msg) == 0)
        {
            break;
        }
    }

    close(client_sock);

    return 0;
}

3、测试结果

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值