Unix/Linux C 编程,简单的socket客户端

简单的socket客户端

功能:连接指定的服务器,每隔1s发送一个随机数

关键字:socket,客户端,多线程,信号量,随机数

思路:

使用双线程生产消费模式,主线程消费,子线程生产,两者之前使用信号量通信。

Code:

#include <sys/types.h>
#include <sys/socket.h>     /* socket */
#include <stdio.h>
#include <string.h>
#include <netinet/in.h>     /* IPV4 地址家族 */
#include <arpa/inet.h>      /* inet_pton */
#include <unistd.h>
#include <stdint.h>
#include <pthread.h>
#include <semaphore.h>      // 信号量



char buf[128] = {0};
sem_t sem_dataready;

static void* ProducerThread(void* arg);
static int Connect(char* serverip, uint16_t port);

int main(int argc, char** argv)
{
    if (argc != 3) {
        printf("\r\nError Usage!\r\n");
        printf("    Usage: client <serverip> <port>");
    }

    pthread_t tid;
    char* serverip = argv[1];
    uint16_t port = atoi(argv[2]);
    int cfd = Connect(serverip, port);                          // 连接目标服务器,返回socket描述符

    write(cfd, "connect success", strlen("connect success"));

    sem_init(&sem_dataready, 0, 0);                             // 初始化信号量
    pthread_create(&tid, NULL, ProducerThread, NULL);           // 创建生产者线程

    while(1){                                                   // 消费者循环
        sem_wait(&sem_dataready);                               // 等待数据OK
        send(cfd, buf, strlen(buf), MSG_DONTWAIT);              // 发送随机数到服务器
    }

    sem_destroy(&sem_dataready);
    close(cfd);

    return 0;
}





static void* ProducerThread(void* arg)      // 生产者子线程
{
    srand(time(0));
    int num;
    while(1){
        num = rand() % 65536;
        sprintf(buf, "%d\r\n", num);
        sem_post(&sem_dataready);           // 通知主线程数据OK
        printf("num = %d\r\n", num);
        sleep(1);
    }
    return NULL;
}


static int Connect(char* serverip, uint16_t port)
{
    struct sockaddr_in serv;
    int fd = socket(AF_INET, SOCK_STREAM, 0);           /* 创建socket,返回文件描述符 */
    if (fd == -1){
        printf("get socket fd err\r\n");
        return -1;
    }

    serv.sin_family = AF_INET;                          /* 指定为IPv4地址 */
    serv.sin_port = htons(port);                        /* 端口,主机序转网络序 */
    inet_pton(AF_INET, serverip, &serv.sin_addr);       /* 转换ip字符串为ipv4地址结构 */

    if(connect(fd, (struct sockaddr*)&serv, sizeof(serv)) == -1){/* 使用fd发起连接*/
        printf("connect failed, server not found or port incorrect\r\n");
        return -1;
    }
    return fd;
}

编译:

$ gcc client.c -o client -lpthread
$ client 192.168.1.13 8080

运行:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值