c - 通过 TCP 发送和接收结构体

标签 c tcp

我必须在客户端中输入两个字符串并将它们与结构一起发送到服务器。然后服务器执行c = a + b并向客户端发送带有{a, b, c }的新闻结构。如果收到的abquit,服务器会向客户端发送bye

客户端接收结构并打印c。如果是bye,则关闭连接,否则返回询问ab的输入,并再次开始循环。

客户:

    #if defined WIN32
    #include <Winsock2.h>
    #else
    #define closesocket close
    #include <sys/socket.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    #endif
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>

    #define BUFSIZE 30

    void ClearWinSock() {
    #if defined WIN32
        WSACleanup();
    #endif
    }

    //-----------------------------INIZIALIZZAZIONE WSADATA

    int main (void) {
    #if defined WIN32

        WSADATA wsaData;
        int iResult = WSAStartup (MAKEWORD (2,2), &wsaData);

        if (iResult !=0) {
            printf ("error at WSASturtup\n");
            return 0;
            }

    #endif

    //--------------------------------CREAZIONE SOCKET

        int Csocket;

        Csocket = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);

        if (Csocket < 0) {

        printf ("socket creation failed");
        closesocket (Csocket);
        ClearWinSock();
        return 0;
        }

        char s_address[BUFSIZE];
                printf ("Inserisci l'indirizzo dell'host a cui connetterti\n");
                scanf ("%s", s_address);

                int port;
                printf ("Inserisci la porta a cui connetterti\n");
                scanf("%d", &port);

                struct sockaddr_in sad;
                    memset (&sad, 0, sizeof(sad));
                    sad.sin_family = AF_INET;
                    sad.sin_addr.s_addr = inet_addr(s_address);
                    sad.sin_port = htons (port);

    //------------------------------CONNESSIONE AL SERVER

       if (connect(Csocket, (struct sockaddr*) &sad, sizeof(sad)) < 0) {
            printf ("failed to connect\n");
            closesocket (Csocket);
            ClearWinSock();
            return 0;
       }

    //-----------------------------RICEZIONE STRINGA DAL SERVER

       char buf[BUFSIZE];

       int read = recv (Csocket, buf, BUFSIZE - 1, 0);

       if (read <=0) {

        printf ("Qualcosa non và!\n");
       }

       else {
        buf[read] = '\0';  //tappo stringa per sicurezza
        printf("Server scrive: %s\n", buf);
       }


    //------------------------------STRUTTURA DI STRINGHE

         struct stringab {
                                char a[30];
                                char b[30];
                                char c[70];
                            } ab;


                            void* abptr = &ab;


                printf ("Inserisci prima stringa\n");
                scanf ("%s", ab.a);


                            printf ("Inserisci seconda stringa\n");
                            scanf ("%s", ab.b);



        if (send(Csocket, (char*)abptr, sizeof(ab), 0) != sizeof(ab)) {
               printf("client-send() sent a different number of bytes than expected");
               closesocket(Csocket);
               ClearWinSock();
               system ("pause");
               return 0;
           }

 printf ("\n");
   closesocket (Csocket);
   system ("pause");
   ClearWinSock();
   return 0;

   }

服务器:

#if defined WIN32
#include <Winsock2.h>
#else
#define closesocket close
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define BUFSIZE 30

void ClearWinSock() {
#if defined WIN32
    WSACleanup();
#endif
}

int main(void) {

//---------------------------INIZIALIZZAZIONE WSADATA

#if defined WIN32

    WSADATA wsaData;
    int iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
    if (iResult != 0) {
        printf ("Error at WSAStartup");
        return 0;
    }

#endif

//-------------------------------CREAZIONE SOCKET

    int Mysocket;
    Mysocket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);

    //Valutare la presenza di errori per assicurarsi che la socket sia valida.
    if (Mysocket < 0) {
        printf("socket creation failed\n");
        return 0;
    }

    //Assegnazione indirizzo alla socket.
    struct sockaddr_in sad;
    memset(&sad, 0, sizeof(sad));
    sad.sin_family = AF_INET;
    sad.sin_addr.s_addr = inet_addr ("127.0.0.1");
    sad.sin_port = htons (9888);

//------------------------ASSEGNAZIONE PORTA E IP ALLA SOCKET

if (bind(Mysocket, (struct sockaddr*) &sad, sizeof(sad)) < 0) {
    printf ("bind() failed\n");
    closesocket(Mysocket);
    return 0;
}

//---------------------------SETTAGGIO SOCKET ALL'ASCOLTO

int qlen = 10; //numero client che il server può gestire

if (listen (Mysocket, qlen) < 0) {

    printf("listen() failed\n");
    closesocket(Mysocket);
    return 0;
}

struct sockaddr_in cad;  // struttura per l'indirizzo del cient
int Csocket;             // descrittore socket per il client
int clientlen;           // lunghezza indirizzo del client

//------------------------------ACCETTA LA CONNESSIONE

while (1) {

    printf("In attesa di un client con cui comunicare...\n");
    memset(&cad, 0, sizeof(cad));
    clientlen = sizeof(cad);       // assegna la dimensione dell'indirizzo del client

    if((Csocket = accept(Mysocket, (struct sockaddr*) &cad, &clientlen)) < 0) {
        printf ("accept failed\n");
        closesocket(Mysocket);
        ClearWinSock();
        return 0;
    }


    printf("Connessione stabilita con il client il cui indirizzo e' %s \n\n", inet_ntoa(cad.sin_addr));

//---------------------------------------INVIO STRINGA AL CLIENT

    char* inputString = "Connessione avvenuta!";
    int stringlen = strlen(inputString);


    if (send(Csocket, inputString, stringlen, 0) != stringlen) {
        printf("client-send() sent a different number of bytes than expected");
        closesocket(Csocket);
        ClearWinSock();
        system ("pause");
        return 0;
    }

printf ("\n");
closesocket (Csocket);
system ("pause");
ClearWinSock();
return 0;

}

那么,我是否以这种方式将结构发送到服务器?服务器如何recv()这个结构体并c = a + b重新构建并重新发送该结构体?

最佳答案

我解决了发送端和接收端的问题,如下所示:

send(Csocket, (char*)abptr, sizeof(ab), 0);

recv (Csocket, (char*)abptr, sizeof(ab), 0);

所以我传递了结构体,两边都有一个结构体指针。我认为这是本地托管的一个很好的解决方案,也许您需要一个更好的网络解决方案(安全原因)。

关于c - 通过 TCP 发送和接收结构体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46914631/

相关文章:

c - 将字符指针的值赋给字符数组

c - Microsoft 编译器下 _rdrand_step 内在函数的可用性?

c - C 是否提供 API 来以编程方式获取系统上最大可能的并发线程数?

c - 删除链表 C 时出现段错误

delphi - TCP 客户端未接收到来自 RTSP 服务器的响应

java - 无法将 void 转换为 "classname"

c - 为什么 EOF 与有效的 char 值一致?

c - 什么操作导致 select 函数在检测套接字的写入状态时超时。

sockets - RST上的TCP重传-Windows和Linux上的套接字行为不同?

objective-c - GCDAsyncSocket 错误