首页 > 系统相关 >Linux网络编程:socket实现client/server通信

Linux网络编程:socket实现client/server通信

时间:2023-05-11 11:33:48浏览次数:45  
标签:sockaddr addr int server client 接字 include socket

一、问题引入

阅读UNIX网络编程 卷1:套接字联网API 第3版的前4个章节,觉得有必要对书籍上的源码案例进行复现,并推敲TCP的C/S通信过程。

二、解决过程

2-1 server

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/shm.h>

#define PORT 8887
#define QUEUE 20
#define BUFFER_SIZE 1024

int main()
{
    // 定义sockfd, AF_INET:IPv4协议,SOCK_STREAM:字节流套接字
    int server_sockfd = socket(AF_INET, SOCK_STREAM, 0);

    // 定义sockaddr_in
    struct sockaddr_in server_sockaddr;
    server_sockaddr.sin_family = AF_INET;
    server_sockaddr.sin_port = htons(PORT);
    server_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);

    // bind,成功返回0,出错返回-1
    if (bind(server_sockfd, (struct sockaddr *)&server_sockaddr, sizeof(server_sockaddr)) == -1)
    {
        perror("bind failure");
        exit(1);
    }

    // listen,成功返回0,出错返回-1
    if (listen(server_sockfd, QUEUE) == -1)
    {
        perror("listen failure");
        exit(1);
    }

    // 客户端套接字
    char buffer[BUFFER_SIZE];
    struct sockaddr_in client_addr;
    socklen_t length = sizeof(client_addr);

    // 成功返回非负描述字,出错返回-1
    // accept()被阻塞,等待客户端连接,一旦客户端和服务器完成TCP三次握手,accept()返回一个已连接描述值
    int conn = accept(server_sockfd, (struct sockaddr *)&client_addr, &length);
    if (conn < 0)
    {
        perror("connect failure");
        exit(1);
    }

    printf("**************************\n");
    printf("accept successful !!!\n");
    char ipbuf[64] = {0};
    printf("client || ip: %s, port: %d\n",
           inet_ntop(AF_INET, &client_addr.sin_addr.s_addr, ipbuf, sizeof(ipbuf)),
           ntohs(client_addr.sin_port));
    printf("**************************\n");
    while (1)
    {
        memset(buffer, 0, sizeof(buffer));
        // 接收
        int len = recv(conn, buffer, sizeof(buffer), 0);
        if (strcmp(buffer, "exit") == 0 || strcmp(buffer, "q") == 0)
            break;
        if(len > 0)
        {
            printf("Recv:%s (%d Byte)\n", buffer, strlen(buffer));
        }
    }
    close(conn);
    close(server_sockfd);
    return 0;
}

2-2 client

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/shm.h>

#define PORT 8887
#define BUFFER_SIZE 1024

int main()
{
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    struct sockaddr_in servaddr;
    memset(&servaddr, 0, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(PORT);
    servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
    /// 连接服务器,成功返回0,错误返回-1
    if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0)
    {
        perror("connect");
        exit(1);
    }
    printf("**************************\n");
    printf("connect successful !!!\n");
    char ipbuf[64] = {0};
    printf("server || ip: %s, port: %d\n",
           inet_ntop(AF_INET, &servaddr.sin_addr.s_addr, ipbuf, sizeof(ipbuf)),
           ntohs(servaddr.sin_port));
    printf("now you can send message to server\n");
    printf("**************************\n");
    char sendbuf[BUFFER_SIZE];
    while (fgets(sendbuf, sizeof(sendbuf), stdin) != NULL)
    {
        if(sendbuf[strlen(sendbuf)-1] == '\n')
            sendbuf[strlen(sendbuf)-1] = '\0';
        // 发送
        send(sockfd, sendbuf, strlen(sendbuf), 0);
        if (strcmp(sendbuf, "exit") == 0 || strcmp(sendbuf, "q") == 0)
            break;
        memset(sendbuf, 0, sizeof(sendbuf));
    }
    close(sockfd);
    return 0;
}

2-3 编译和运行测试

标签:sockaddr,addr,int,server,client,接字,include,socket
From: https://www.cnblogs.com/caojun97/p/17356425.html

相关文章

  • socket机制
    1.概述:Socket,又称为套接字,用于描述IP地址和端口。应用程序通常通过socket向网络发出请求或者应答网络请求。Socket就是网络编程提供的一种机制:通信两端都有socket;网络通信其实就是socket之间的通信;数据在两个socket之间通过io传输。网络编程也称作为socket编程,套接字编程。......
  • HTTP协议客户端之HttpClient介绍及使用
    1.HttpClient介绍HttpClient是ApacheJakartaCommon下的子项目,可以用来提供高效的、最新的、功能丰富的支持HTTP协议的客户端编程工具包,并且它支持HTTP协议最新的版本和建议。HttpClient相比JDK自带的URLConnection,增加了易用性和灵活性,使客户端发送Http请求变得更加容......
  • ubuntu server版操作系统安装步骤记录
    组内有一个项目支持的时centos的操作系统,后续因为有ubuntu的需求,需要测一下ubuntun操作系统的兼容性,测试前期需要手动为测试服务器装ubuntu的操作系统,因此,这里记录一下自己装ubuntun操作系统的步骤由于项目使用的是ubuntu是18.04.6版本,这里就只记录的是此版本的安装步骤1、下载u......
  • MSSqlServer 出错 9003 错误
      MSSqlServer出错9003错误传递给数据库'PerDB'中的日志扫描操作的日志扫描号(227783:55280:433)无效。此错误可能指示数据损坏,或者日志文件(.ldf)与数据文件(.mdf)不匹配。如果此错误是在复制期间出现的,请重新创建发布。否则,如果该问题导致启动期间出错,请从备份还原......
  • 用sql语句实现sqlserver不同库间表相互同步
    同步表的方式有很多种因为不想太过于麻烦所以就用存储过程来实现某些表同步createproccopytbaleas--表名declare@namenvarchar(50)--创建表declare@createtablenvarchar(200)--删除表declare@deletetablenvarchar(200)--定义游标declaretabnameCURSORF......
  • GeoServer发布图层栅格格式设置样式
    最近工作中使用到了geoserver发布tif图,发布图层后需要给图层设置样式。发布图层就不在这里说了,可以参考其他博客,主要记录一下编写图层样式。一、介绍1、图层类型在geoserver中图层类型分为以下几类:我们可以在管理界面中查看我们发布的图层类型,后面写样式时需要根据我......
  • SQLSERVER获取汉字拼音码
     用户的输入经常用到拼音码选择器 --调用方法select dbo.wsh_GetPY('汉字')ALTERFUNCTION[dbo].[wsh_GetPY](@strNVARCHAR(4000))RETURNSNVARCHAR(4000)ASBEGINDECLARE@WORDNCHAR(1),@PYNVARCHAR(4000)SET@PY=''WHILELEN(@STR)>0BEGI......
  • 推荐一个.Net Core开发的Websocket群聊、私聊的开源项目
    今天给大家推荐一个使用Websocket协议实现的、高性能即时聊天组件,可用于群聊、好友聊天、游戏直播等场景。项目简介这是一个基于.NetCore开发的、简单、高性能的通讯组件,支持点对点发送、群聊、在线状态的订阅。该项目还包含群聊例子,可以用于学习。技术架构1、跨平台:基于.Ne......
  • 简述2012版SQL SERVER备份还原到2008R2版SQL SERVER的方法(转载)
    转载:http://wfsj.weifang.gov.cn/sy/sjjl/201905/t20190531_5370608.html 目前审计机关数据分析通用的数据库为SQLSERVER2008R2版本。被审计单位相关业务系统的后台数据库主要是ORACLE、SQLSERVER 。审计人员需要将不同类型或者不同SQLSERVER版本的数据库转化到SQLSERVER......
  • C# HttpListener 和 HttpServer区别
    HttpListener和HttpServer都是C#中用于创建HTTP服务器的类库,它们的作用都是监听HTTP请求,并向客户端发送HTTP响应。它们的主要区别在于实现方式和使用场景。HttpListener是.NETFramework中的一个类,它提供了一种基于事件的异步API,可以用于创建一个轻量级的HTTP服......