Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (GNU/Linux, *NIX, *BSD und Co) » simple Tcp-verbindung

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 < [ 2 ]
000
22.01.2003, 21:02 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


Hallo,
wie schreib ich ein Programm das mir eine Simple TCP-IP-Verbindung zu einer bestimmten Ip und Port erstellt und ich dann empfangen und senden kann (nicht asynchron sondern synchron)

Falls ich das mit eurer Hilfe hinbekomm, fallen auch meine beiden anderen Fragen (pipes, etc) weg ...
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
23.01.2003, 08:36 Uhr
virtual
Sexiest Bit alive
(Operator)


Hm. Das ist jetzt wirklich nur schnell zusammen gehackt:
Der Server sieht so aus:

C++:
/*recv.c*/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <ctype.h>

static int handle_request(int);

static const char* prgname;

int
main(
    int argc,
    char** argv)
{
    unsigned short lport;
    int lsocket;
    char lhostname[64];
    struct hostent* lhostentry;    
    struct sockaddr_in laddr;
    static int quit = 0;

    /*
     * Get application name
     */

    prgname = *argv + strlen(*argv);
    while (prgname != *argv && prgname[-1]!='/') prgname--;

    /*
     * Check command line
     */

    if (argc!=2)
    {
        fprintf(stderr, "error: %s: invalid command line.\n"
                        "usage: %s tcp-port\n",
                        prgname, prgname);
        exit(EXIT_FAILURE);
     }
      if (1!=sscanf(argv[1], "%hu", &lport))
    {
        fprintf(stderr, "error: %s: expected unsigned integer (port number)\n"
                        "usage: %s tcp-port\n",
                        prgname, prgname);
        exit(EXIT_FAILURE);
    }

    /*
     * Say hello
     */

    printf("%s - simple TCP server demo\n"
           "Listens for incoming client connections and executes\n"
           "the received strings in a shell. The program terminates\n"
           "when a line with the text \"exit\" is received.\n",
            prgname);

    /*
     * Setup address information
     */

    if (-1 == gethostname(lhostname, sizeof(lhostname)))
    {
        fprintf(stderr, "error: %s: gethostname() failed: %s\n", prgname, strerror(errno));
        exit(EXIT_FAILURE);
    }
    lhostentry = gethostbyname(lhostname);
    if (NULL == lhostentry)
    {
        fprintf(stderr, "error: %s: gethostbyname() failed: %s\n", prgname, strerror(errno));
        exit(EXIT_FAILURE);
    }
    memset(&laddr, 0, sizeof(laddr));
    laddr.sin_family = lhostentry->h_addrtype;
    memcpy((char*)&laddr.sin_addr, lhostentry->h_addr, lhostentry->h_length);
    laddr.sin_port = htons(lport);

    /*
     * Create socket
     */

    lsocket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (-1 == lsocket)
    {
        fprintf(stderr, "error: %s: socket() failed: %s\n", prgname, strerror(errno));
        exit(EXIT_FAILURE);
    }

    /*
     * Bind socket to address
     */

    if (-1 == bind(lsocket, &laddr, sizeof(laddr)))
    {
        fprintf(stderr, "error: %s: bind() failed: %s\n", prgname, strerror(errno));
        close(lsocket);
        exit(EXIT_FAILURE);
    }

    /*
     * Set back log
     */

    if (-1 == listen(lsocket, 10))
    {
        fprintf(stderr, "error: %s: listen() failed: %s\n", prgname, strerror(errno));
        close(lsocket);
        exit(EXIT_FAILURE);
    }
    
    /*
     * Enter loop for receiving requests
     */

    printf("Waiting for connection at %s:%hu...\n", lhostname, lport);
    do
    {
        int csocket;
        struct sockaddr_in caddr;
        socklen_t clen;

        /*
         * Accept a connection
         */

        clen = sizeof(caddr);
        csocket = accept(lsocket, &caddr, &clen);
        if (-1 == csocket)
        {
            fprintf(stderr, "warning: %s: accept() failed: %s\n", prgname, strerror(errno));
            continue;
        }
        
        /*
         * Handle client request
         */

        quit = handle_request(csocket);
    } while(!quit);

    /*
       * cleanup
     */

    close(lsocket);
}


int
handle_request(
    int csocket)
{
    char* buffer = NULL;
    char* tmp;
    size_t size = 0;
    size_t len = 0;
    size_t chunk;
    int quit = 0;
    /*
     * Fetch command from stream
     */

    for(;;)
    {
        /*
         * Resize receive buffer
         */

        size += 1024;
        tmp = realloc(buffer, size);
        if (NULL == tmp)
        {
            if (NULL != buffer) free(buffer);
            close(csocket);
            fprintf(stderr, "warning: %s: realloc(%u) failed.\n", prgname, size);
            return 0;
        }
        buffer = tmp;
        
        /*
         * Get next portion
         */

        chunk = read(csocket, buffer+len, size-len-1);
        if (chunk>=0)
        {
            buffer[len+chunk] = 0;
        }
        if (size-len-1>chunk) break;
        len += chunk;            
    }
    if (chunk<0)
    {
            if (NULL != buffer) free(buffer);
            close(csocket);
            fprintf(stderr, "warning: %s: read() failed: %s.\n", prgname, strerror(errno));
            return 0;
    }
    len += chunk;
    while (len>0 && iscntrl(buffer[len-1])) buffer[--len] = 0;

    /*
     * Print command
     */

    printf("Got command: >%s<\n", buffer);
    if (strcmp(buffer, "exit"))
    {
        system(buffer);
    }else
    {
        printf("Program will be finished\n");
        quit = 1;
    }

    /*
     * cleanup
     */

    free(buffer);
    close(csocket);
    return quit;
}


Es ist ein simples Demo: es öffnet ein TCP Socket für den Port, den du über kommandozeile angibst und empfängt dort nachrichten. Wenn die Nachricht "exit" ist, beendet sich das Programm; ansonsten führt es die Nachricht als Command in der Shell aus.
Als client kannst Du auch ein telnet nehmen:

Code:
telnet rechnername tcp-port


Dann Die Nachricht eintippen, gefolgt von CTRL-D. Alternativ nächste Antwort von mir in diesem Thread lesen.

Ein "echter" Server würde vermutlich jeden Clientrequest in einem separatem Thread beantworten; auch kann man sicherlich noch nach dem accept mehr informationen ausgeben, welcher Client sich connected hat. Aber das wirst Du schon hinbekommen...
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)

Dieser Post wurde am 23.01.2003 um 08:36 Uhr von virtual editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
23.01.2003, 08:38 Uhr
virtual
Sexiest Bit alive
(Operator)


Das könnte man als passenden Client nehmen:

C++:
/* send.c */
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <ctype.h>


int
main(
    int argc,
    char** argv)
{
    const char* prgname;
    unsigned short port;
    size_t command_len;
    char* command;
    int i;
    struct hostent* hostentry;
    struct sockaddr_in addr;
    int csocket;

    /*
     * Get application name
     */

    prgname = *argv + strlen(*argv);
    while (prgname != *argv && prgname[-1]!='/') prgname--;

    /*
     * Check command line
     */

    if (argc<=3)
    {
        fprintf(stderr, "error: %s: invalid command line.\n"
                        "usage: %s host tcp-port [command+args]\n",
                        prgname, prgname);
        exit(EXIT_FAILURE);
     }
      if (1!=sscanf(argv[2], "%hu", &port))
    {
        fprintf(stderr, "error: %s: expected unsigned integer (port number)\n"
                        "usage: %s host tcp-port [command+args]\n",
                        prgname, prgname);
        exit(EXIT_FAILURE);
    }
    command_len = 0;
    for(i=3; i<argc; ++i)
        command_len += 3+strlen(argv[ i ]);
    command = malloc(command_len);
    if (NULL == command)
    {
        fprintf(stderr, "error: %s: malloc() failed: %s\n", prgname, strerror(errno));
        exit(EXIT_FAILURE);
    }    
    strcpy(command, argv[3]);
    for(i=4; i<argc; ++i)
    {
        strcat(command, " \"");
        strcat(command, argv[ i ]);
        strcat(command, "\"");
    }

    /*
     * Get server address
     */

    hostentry = gethostbyname(argv[1]);
    if (NULL == hostentry)
    {
        fprintf(stderr, "error: %s: gethostbyname() failed: %s\n", prgname, strerror(errno));
        free(command);
        exit(EXIT_FAILURE);
    }
    memset(&addr, 0, sizeof(addr));
    addr.sin_family = hostentry->h_addrtype;
    memcpy((char*)&addr.sin_addr, hostentry->h_addr, hostentry->h_length);
    addr.sin_port = htons(port);

    /*
     * Create TCP socket
     */

    csocket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (-1 == csocket)
    {
        fprintf(stderr, "error: %s: socket() failed: %s\n", prgname, strerror(errno));
        free(command);
        exit(EXIT_FAILURE);
    }
    
    /*
     * Connect to server
     */

    if (-1 == connect(csocket, &addr, sizeof(addr)))
    {
        fprintf(stderr, "error: %s: connect() failed: %s\n", prgname, strerror(errno));
        close(csocket);
        free(command);
        exit(EXIT_FAILURE);
    }

    /*
     * Write message to server
     */

    if (strlen(command)!=write(csocket, command, strlen(command)))
    {
        fprintf(stderr, "error: %s: write() failed: %s\n", prgname, strerror(errno));
        close(csocket);
        free(command);
        exit(EXIT_FAILURE);
    }

    close(csocket);
    free(command);
}


--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
23.01.2003, 14:56 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


Super!
Genau das was ich gesucht hab!
Hoffentlich komm ich etz weiter mit meinem Problem!

lesen geht dann analog oder?


C++:
read(csocket, command, strlen(command)));


--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
23.01.2003, 15:05 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


hmm ich krieg nur beim compilieren folgende errors:


Code:
main.cpp: In function `int main(int, char **)':
main.cpp:25: implicit declaration of function `int strerror(...)'
main.cpp:30: implicit declaration of function `int memset(...)'
main.cpp:36: `csocket' undeclared (first use this function)
main.cpp:36: (Each undeclared identifier is reported only once
main.cpp:36: for each function it appears in.)
main.cpp:43: ANSI C++ forbids implicit conversion from `void *' in assignment
main.cpp:50: type `const sockaddr' is not a base type for type `sockaddr_in'
main.cpp:53: implicit declaration of function `int close(...)'
main.cpp:58: implicit declaration of function `int read(...)'
main.cpp:71: implicit declaration of function `int write(...)'


--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
23.01.2003, 15:06 Uhr
virtual
Sexiest Bit alive
(Operator)


Ist C, nicht C++ code.
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
23.01.2003, 15:53 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


hat nur ein header gefehlt


C++:
#include <unistd.h>



nur im moment hab ich folgendes problem:

Client:

C++:
int send(int sock,char *cmd, int len)
{
  printf("Sending %d Bytes of Data: %s\n",len,cmd);
  int written = 0;
  char data[2] = {0,0};
  for(int x = 0; x < len; x++)
  {
    data[0] = cmd[x];
    written += write(sock, data, 1);
    printf("%d ",cmd[x]);
  }
  printf("\nWritten %d Bytes\n\n",written);


Sending 13 Bytes of Data: Admin-FloSoft
65 100 109 105 110 45 70 108 111 83 111 102 116
Written 13 Bytes

Server:

Code:
Socket 7 connected from 192.168.123.10.
Error receiving data from socket 7.
The packet length (1768776769) is greater than the buffer length.(1024)
Error receiving data from socket 7.
Login attempt from IP 192.168.123.10 failed: userid= password=
Socket 7 from 192.168.123.10 closed.


(Quellcode vom Server hab ich zwar nur nützt mir der nicht viel)
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
23.01.2003, 16:17 Uhr
virtual
Sexiest Bit alive
(Operator)


Hm. Vielleicht nutzt aber den Lesern des Forums der Quellcode des Servers an der entscheidenden Stelle?
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
23.01.2003, 18:33 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


oh ja:

Socket erstellen vom server:

C++:
//...
    setsockopt( sock, SOL_SOCKET, SO_REUSEADDR, (char*)&opt, sizeof(opt));
    struct LINGER lingerOpt;
    memset(&lingerOpt, 0x00, sizeof(lingerOpt));
    lingerOpt.l_onoff = 1;
    lingerOpt.l_linger = 60;
    setsockopt( sock, SOL_SOCKET, SO_LINGER, (char*)&lingerOpt, sizeof(lingerOpt));
    SOCKADDR_IN sin;
    sin.sin_family = AF_INET;
    sin.sin_port = htons(iServerPort);
    sin.sin_addr.s_addr = 0;
    int result = bind(sock, (LPSOCKADDR) &sin, sizeof(sin));
// ...




C++:
// ...
    char crlf[] = {0x0d, 0x0a, 0x00};

    SOCKADDR_IN sin;
    sin.sin_family = AF_INET;
    bind(pThread->sock, (LPSOCKADDR) &sin, sizeof(sin));
    connect(pThread->sock, (LPSOCKADDR) &sin, sizeof(sin));
    struct LINGER opt;
    opt.l_onoff = 1;
    opt.l_linger = 60;
    setsockopt(pThread->sock, SOL_SOCKET, SO_LINGER, (const char *)&opt, sizeof(opt));
    char szBuf[MAX_BUFFER];
    char szIn[MAX_BUFFER];
    int nBytes = 0;
    sprintf(szBuf, "AxisSvr connected.%s%sUsername: ", crlf, crlf);
    Send(pThread->sock, szBuf, strlen(szBuf));
    memset(&szIn[0], 0x00, sizeof(szIn));
    nBytes = Receive(pThread->sock, szIn, sizeof(szIn));
    if ( nBytes < 0 )
    {
        shutdown(pThread->sock, 2 );
        SysMessage("Error receiving data on socket %ld.  Closing\n", (int) pThread->sock);
        SysMessage("Socket %ld from %s closed.\n", (int) pThread->sock, pThread->szIPAddr);
        close(pThread->sock);
        return NULL;
    }
    szIn[nBytes] = 0x00;
    Trim(&szIn[0], strlen(szIn));
    char szUserID[MAX_PATH];
    char szPassword[MAX_PATH];
    memset(&szUserID[0], 0x00, sizeof(szUserID));
    memset(&szPassword[0], 0x00, sizeof(szPassword));
    memcpy(szUserID, szIn, strlen(szIn));
    sprintf(szBuf, "Password: ");
    Send(pThread->sock, szBuf, strlen(szBuf));
    memset(&szIn[0], 0x00, sizeof(szIn));
    nBytes = Receive(pThread->sock, &szIn[0], sizeof(szIn));
    if ( nBytes < 0 )
    {
        shutdown(pThread->sock, 2 );
        SysMessage("Error receiving data on socket %ld.  Closing\n", (int) pThread->sock);
        SysMessage("Socket %ld from %s closed.\n", (int) pThread->sock, pThread->szIPAddr);
        close(pThread->sock);
        return NULL;
    }
//...




LOL was mir grad auffällt.... der offizielle windows client funktioniert auch nicht! die ham da scheinbar irgendeine sch... gebaut
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
24.01.2003, 11:29 Uhr
virtual
Sexiest Bit alive
(Operator)


Sieht aber ziemlich Windowslastig aus, der Code.
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 < [ 2 ]     [ C / C++ (GNU/Linux, *NIX, *BSD und Co) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: