[Linux高性能服务器]socket编程实践(1)--简单的客户端服务器

7 篇文章 0 订阅
4 篇文章 0 订阅

摘要

  • 为了后面能够很好的查找和参考实现一个简单的服务器和客户端,使用了socket编程中的基本函数. 实现了TCP和UDP两种版本
  • 这一部分仅就实现最核心的功能,连接并且通信.后续更多功能(并发,IO复用)再慢慢总结
  • 对下面的内容有问题请移步参考Linux网络编程基础API
  • 运行环境为Linux

socket编程实践(1)

TCP

服务器端
/**
 * @File:serv_1.cpp
 * @Descripttion: socket编程服务器端,简单版本(TCP)
 *  只接受一个客户端连接,并接收客户端发送的信息显示后就退出
 * @Version: 
 * @Author: zsj
 * @Date: 2020-05-03 15:38:31
 * @LastEditors: zsj
 * @LastEditTime: 2020-05-03 16:20:39
 */
#include<cstdio>
#include<cstdlib>
#include<sys/types.h>
#include<sys/socket.h>
#include<unistd.h>
#include<arpa/inet.h>
#include<cstring>

void show_error(char * info){
    printf(info);
    exit(-1);
}

int main(int argc,char * argv[])
{
    //参数数量不对直接返回
    if(argc < 2){
        printf("Usage: %s <port>\n",argv[0]);
        exit(-1);
    }

    // 创建一个socket
    int listenfd = socket(PF_INET,SOCK_STREAM,0);
    if(listenfd == -1){
        show_error("socket() error!");
    }

    // 设置socket地址
    struct sockaddr_in serv_addr;
    memset(&serv_addr,0,sizeof(serv_addr));
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(atoi(argv[1]));

    //分配地址信息,socket命名
    int ret = bind(listenfd,(struct sockaddr*)&serv_addr,sizeof(serv_addr));
    if(ret == -1){
        show_error("bind() error!");
    }

    //创建一个监听队列
    ret = listen(listenfd,5);
    if(ret == -1){
        show_error("listen() error!");
    }

    struct sockaddr_in clnt_addr;
    socklen_t clnt_addr_sz = sizeof(clnt_addr);
    //取出一个连接
    int clnt_sock = accept(listenfd,(struct sockaddr*)&clnt_addr,&clnt_addr_sz);
    if(clnt_sock == -1){
        show_error("accept() error!");
    }
    else{
        printf("get a connection %d\n",clnt_sock);
    }

    char buffer[128];
    //读取数据
    ret = read(clnt_sock,buffer,sizeof(buffer));
    if(ret < 0){
        show_error("read() error!");
    }
    else if(ret == 0){
        printf("client close the connection!");
    }
    else{
        printf("from %d data %d bytes: %s\n",clnt_sock,ret,buffer);
    }

    close(clnt_sock);
    close(listenfd);
}
客户端
/**
 * @File:clnt_1.cpp
 * @Descripttion: socket编程,客户端简单版本,(TCP)
 *  连接服务器之后,发送数据到服务器之后就退出
 * @Version: 
 * @Author: zsj
 * @Date: 2020-05-03 16:06:36
 * @LastEditors: zsj
 * @LastEditTime: 2020-05-03 16:19:46
 */
#include<cstdio>
#include<cstdlib>
#include<sys/types.h>
#include<sys/socket.h>
#include<unistd.h>
#include<arpa/inet.h>
#include<cstring>


void show_error(char * info){
    printf(info);
    exit(-1);
}

int main(int argc,char * argv[])
{
    if(argc < 3){
        printf("Usage: %s <ip> <port>\n",argv[0]);
        exit(-1);
    }

    //创建一个socket
    int clnt_sock = socket(PF_INET,SOCK_STREAM,0);
    if(clnt_sock == -1){
        show_error("socket() error!");
    }

    //客户端不需要绑定和监听,直接连接服务器
    struct sockaddr_in serv_addr;
    memset(&serv_addr,0,sizeof(serv_addr));
    serv_addr.sin_port = htons(atoi(argv[2]));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = inet_addr(argv[1]);

    int ret = connect(clnt_sock,(struct sockaddr*)&serv_addr,sizeof(serv_addr));
    if(ret == -1){
        show_error("connect() error!");
    }
    else{
        printf("connect to %s success!\n",argv[1]);
    }

    //发送数据
    char buffer[128] = "hello server!!!";
    ret = write(clnt_sock,buffer,sizeof(buffer));
    if(ret < 0){
        show_error("write() error!");
    }
    else{
        printf("send data success!\n");
    }

    //关闭连接
    close(clnt_sock);

}

UDP

服务器端
/*
 * @File: serv_udp_1.cpp
 * @Descripttion: socket编程服务器端,简单版本(UDP)
 *  只接受一个客户端连接,并接收客户端发送的信息显示后就退出
 * @Version: 
 * @Author: zsj
 * @Date: 2020-05-03 17:05:25
 * @LastEditors: zsj
 * @LastEditTime: 2020-05-03 17:14:33
 */
#include<cstdio>
#include<cstdlib>
#include<sys/types.h>
#include<sys/socket.h>
#include<unistd.h>
#include<arpa/inet.h>
#include<cstring>

void show_error(char * info){
    printf(info);
    exit(-1);
}

int main(int argc,char * argv[])
{
    //参数数量不对直接返回
    if(argc < 2){
        printf("Usage: %s <port>\n",argv[0]);
        exit(-1);
    }

    // 创建一个socket
    int serv_sock = socket(PF_INET,SOCK_DGRAM,0);
    if(serv_sock == -1){
        show_error("socket() error!");
    }

    // 设置socket地址
    struct sockaddr_in serv_addr;
    memset(&serv_addr,0,sizeof(serv_addr));
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(atoi(argv[1]));

    //分配地址信息,socket命名
    int ret = bind(serv_sock,(struct sockaddr*)&serv_addr,sizeof(serv_addr));
    if(ret == -1){
        show_error("bind() error!");
    }


    struct sockaddr_in clnt_addr;
    socklen_t clnt_addr_sz = sizeof(clnt_addr);

    char buffer[128];
    ret = recvfrom(serv_sock,buffer,sizeof(buffer),0,(sockaddr*)&clnt_addr,&clnt_addr_sz);
    if(ret < 0){
        show_error("read() error!");
    }
    else if(ret == 0){
        printf("client close the connection!");
    }
    else{
        printf("from %s data %d bytes: %s\n",inet_ntoa(clnt_addr.sin_addr),ret,buffer);
    }
    close(serv_sock);
}
客户端
/*
 * @File:clnt_udp_1.cpp
 * @Descripttion: socket编程,客户端简单版本(UDP)
 *  连接服务器之后,发送数据到服务器之后就退出
 * @Version: 
 * @Author: zsj
 * @Date: 2020-05-03 16:06:36
 * @LastEditors: zsj
 * @LastEditTime: 2020-05-03 17:16:48
 */
#include<cstdio>
#include<cstdlib>
#include<sys/types.h>
#include<sys/socket.h>
#include<unistd.h>
#include<arpa/inet.h>
#include<cstring>


void show_error(char * info){
    printf(info);
    exit(-1);
}

int main(int argc,char * argv[])
{
    if(argc < 3){
        printf("Usage: %s <ip> <port>\n",argv[0]);
        exit(-1);
    }

    //创建一个socket
    int clnt_sock = socket(PF_INET,SOCK_DGRAM,0);
    if(clnt_sock == -1){
        show_error("socket() error!");
    }

    //客户端不需要绑定和监听,直接连接服务器
    struct sockaddr_in serv_addr;
    memset(&serv_addr,0,sizeof(serv_addr));
    serv_addr.sin_port = htons(atoi(argv[2]));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = inet_addr(argv[1]);

    

    //发送数据
    char buffer[128] = "hello server!!!";
    int ret = sendto(clnt_sock,buffer,sizeof(buffer),0,(sockaddr*)&serv_addr,sizeof(serv_addr));
    if(ret < 0){
        show_error("sendto() error!");
    }
    else{
        printf("send data success!\n");
    }

    //关闭连接
    close(clnt_sock);

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值