Die Methode zum Senden von Ganzzahl-, Struktur- und anderen Daten über TCP

Test Umgebung

  1. Empfänger: x86 Ubuntu
  2. Absender: arm64 Android

Ganzzahl senden

C-Sprache und Socket-Bibliothek zum Senden einer Ganzzahlvariablen (int) an das Clientprogramm.

  1. Es erstellt zunächst einen TCP-Socket und stellt dann eine Verbindung zur angegebenen Serveradresse und zum angegebenen Port her.
  2. Als nächstes konvertiert es eine Ganzzahlvariable (int) in die Netzwerk-Byte-Reihenfolge (Big Endian).
  3. Und verwenden Sie die Funktion send(), um an den Server zu senden. Schließlich wird der Socket geschlossen und beendet
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>

#define SERVER_IP "127.0.0.1" // 服务器IP地址
#define SERVER_PORT 8888 // 服务器端口号

int main(int argc, char* argv[])
{
    const char *ip = SERVER_IP;
    if(argc == 2){
        ip = argv[1];        
    }

    fprintf(stdout, "ip:%s\n", ip);

    int sock; // 套接字描述符
    struct sockaddr_in server; // 服务器地址结构体
    int data = 1234; // 要发送的整型数据
    int n; // 发送或接收的字节数

    // 创建一个TCP套接字
    sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock == -1)
    {
        perror("socket failed");
        exit(1);
    }

    // 设置服务器地址结构体
    memset(&server, 0, sizeof(server));
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = inet_addr(ip);
    server.sin_port = htons(SERVER_PORT);

    // 连接到服务器
    if (connect(sock, (struct sockaddr *)&server, sizeof(server)) == -1)
    {
        perror("connect failed");
        exit(2);
    }

#if 0
    // 将整型数据转换为网络字节序(大端)
    data = htonl(data);

    // 发送整型数据给服务器
    n = send(sock, &data, sizeof(data), 0);
    if (n == -1)
    {
        perror("send failed");
        exit(3);
    }
#else
    unsigned char sendbuf[4];
    sendbuf[0] = data & 0xff;
    sendbuf[1] = (data >> 8) & 0xff;
    sendbuf[2] = (data >> 16) & 0xff;
    sendbuf[3] = (data >> 24) & 0xff;
    // 发送整型数据给服务器
    n = send(sock, sendbuf, sizeof(sendbuf), 0);
    if (n == -1)
    {
        perror("send failed");
        exit(3);
    }
#endif 
    printf("Sent %d bytes to server\n", n);

    // 关闭套接字
    close(sock);

    return 0;
}

Dies ist ein Serverprogramm, das die C-Sprache und die Socket-Bibliothek verwendet, um eine ganzzahlige Variable (int) zu empfangen.

  1. Es erstellt zunächst einen TCP-Socket und bindet dann an die angegebene Adresse und den angegebenen Port.
  2. Als nächstes lauscht es auf Client-Verbindungsanfragen und akzeptiert eine Verbindung.
  3. Dann verwendet es die Funktion recv(), um die vom Client gesendeten ganzzahligen Daten zu empfangen und sie in die Host-Byte-Reihenfolge (Little Endian oder Big Endian) umzuwandeln.
  4. Schließlich druckt es die empfangenen Daten aus und schließt den Socket.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>

#define SERVER_IP "0.0.0.0" // 服务器IP地址
#define SERVER_PORT 8888 // 服务器端口号

int main(int argc, char* argv[])
{
    int sock, client_sock; // 套接字描述符
    struct sockaddr_in server, client; // 服务器和客户端地址结构体
    int data; // 要接收的整型数据
    int n; // 发送或接收的字节数
    int len; // 客户端地址长度

    // 创建一个TCP套接字
    sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock == -1)
    {
        perror("socket failed");
        exit(1);
    }

    // 设置服务器地址结构体
    memset(&server, 0, sizeof(server));
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = inet_addr(SERVER_IP);
    server.sin_port = htons(SERVER_PORT);

    // 绑定套接字到指定的地址和端口
    if (bind(sock, (struct sockaddr *)&server, sizeof(server)) == -1)
    {
        perror("bind failed");
        exit(2);
    }

    // 监听客户端的连接请求,设置最大连接数为5
    if (listen(sock, 5) == -1)
    {
        perror("listen failed");
        exit(3);
    }

    printf("Waiting for client connection...\n");

    // 接受一个客户端的连接,返回一个新的套接字描述符
    len = sizeof(client);
    client_sock = accept(sock, (struct sockaddr *)&client, (socklen_t*)&len);
    if (client_sock == -1)
    {
        perror("accept failed");
        exit(4);
    }

    printf("Connected to client: %s:%d\n", inet_ntoa(client.sin_addr), ntohs(client.sin_port));
#if 0
    // 接收客户端发送的整型数据
    n = recv(client_sock, &data, sizeof(data), 0);
    if (n == -1)
    {
        perror("recv failed");
        exit(5);
    }
    printf("Received %d bytes from client\n", n);

    // 将整型数据转换为主机字节序(小端或大端)
    data = ntohl(data);
#else
    // 接收客户端发送的整型数据
    unsigned char recvbuf[4];
    n = recv(client_sock, recvbuf, sizeof(recvbuf), 0);
    if (n == -1)
    {
        perror("recv failed");
        exit(5);
    }
    printf("Received %d bytes from client\n", n);
    data = (recvbuf[0] & 0xff) | (recvbuf[1] << 8) & 0xff00 | (recvbuf[2]<< 16)&0xff0000 | (recvbuf[3] << 24)&0xff000000;
#endif
    // 打印出接收到的数据
    printf("Data: %d\n", data);

    // 关闭套接字
    close(client_sock);
    close(sock);

    return 0;
}

Sende- und Empfangsstruktur

Absender

#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  
#include <sys/socket.h>  
#include <arpa/inet.h>  
#include <unistd.h>  
  
#define SERVER_IP "127.0.0.1"

// 定义结构体  
struct Data {  
    int id;  
    char name[20];  
};  
  
int main(int argc, char* argv[]) {

    const char* ip = SERVER_IP;
    if(argc == 2){
        ip = argv[1];
    }

    fprintf(stdout, "ip:%s\n", ip);

    int sockfd;  
    struct sockaddr_in server_addr;  
    struct Data data = { 1, "John" };  
  
    // 创建套接字  
    sockfd = socket(AF_INET, SOCK_STREAM, 0);  
    if (sockfd < 0) {  
        perror("socket error");  
        exit(EXIT_FAILURE);  
    }  
  
    // 设置服务器地址信息  
    memset(&server_addr, 0, sizeof(server_addr));  
    server_addr.sin_family = AF_INET;  
    server_addr.sin_addr.s_addr = inet_addr(ip); // 修改为服务器地址  
    server_addr.sin_port = htons(8888); // 修改为服务器端口号  
  
    // 连接服务器  
    if (connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {  
        perror("connect error");  
        exit(EXIT_FAILURE);  
    }  
  
    // 发送结构体数据  
    if (send(sockfd, &data, sizeof(data), 0) < 0) {  
        perror("send error");  
        exit(EXIT_FAILURE);  
    }  
  
    printf("Data sent successfully\n");  
  
    // 关闭套接字  
    close(sockfd);  
  
    return 0;  
}

Empfangsende

#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  
#include <sys/socket.h>  
#include <arpa/inet.h>  
#include <unistd.h>  
  
// 定义结构体  
struct Data {  
    int id;  
    char name[20];  
};  
  
int main() {  
    int sockfd;  
    struct sockaddr_in server_addr, client_addr;  
    struct Data data;  
    socklen_t client_len = sizeof(client_addr);  
  
    // 创建套接字  
    sockfd = socket(AF_INET, SOCK_STREAM, 0);  
    if (sockfd < 0) {  
        perror("socket error");  
        exit(EXIT_FAILURE);  
    }  
  
    // 设置服务器地址信息  
    memset(&server_addr, 0, sizeof(server_addr));  
    server_addr.sin_family = AF_INET;  
    server_addr.sin_addr.s_addr = INADDR_ANY;  
    server_addr.sin_port = htons(8888);  
  
    // 绑定套接字到服务器地址  
    if (bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {  
        perror("bind error");  
        exit(EXIT_FAILURE);  
    }  
  
    // 监听连接  
    if (listen(sockfd, 5) < 0) {  
        perror("listen error");  
        exit(EXIT_FAILURE);  
    }  
  
    printf("Waiting for a connection...\n");  
  
    // 接受客户端连接  
    int connfd = accept(sockfd, (struct sockaddr *)&client_addr, &client_len);  
    if (connfd < 0) {  
        perror("accept error");  
        exit(EXIT_FAILURE);  
    }  
  
    printf("Connection accepted from %s:%d\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));  
  
    // 接收结构体数据  
    if (recv(connfd, &data, sizeof(data), 0) < 0) {  
        perror("recv error");  
        exit(EXIT_FAILURE);  
    }  
  
    printf("Received data: id = %d, name = %s\n", data.id, data.name);  
  
    // 关闭套接字和连接  
    close(connfd);  
    close(sockfd);  
  
    return 0;  
}

Stellen Sie vier Funktionen vor

uint32_t htonl(uint32_t hostlong); // Konvertiert eine 32-Bit-Zahl von der Host-Byte-Reihenfolge in die Netzwerk-Byte-Reihenfolge
uint16_t htons(uint16_t hostshort); // Konvertiert eine 16-Bit-Zahl von der Host-Byte-Reihenfolge in die Netzwerk-Byte-Reihenfolge
uint32_t ntohl(uint32_t netlong); // Konvertieren Sie eine 32-Bit-Zahl von der Netzwerk-Byte-Reihenfolge in die Host-Byte-Reihenfolge.
uint16_t ntohs(uint16_t netshort); // Konvertieren Sie eine 16-Bit-Zahl von der Netzwerk-Byte-Reihenfolge in die Host-Byte-Reihenfolge

Acho que você gosta

Origin blog.csdn.net/CHNIM/article/details/132190405
Recomendado
Clasificación