VB.NET 2010 Express Struktur an Server senden

jkallup

Erfahrenes Mitglied
Hallo

möchte eine struktur über tcp an einen C-Server Programm
übermitteln, doch irgendwie werden die datenfelder nicht
richtug gesetzt.
woran kann das liegen?

Code:
    Structure my_protocol
        Dim type As Integer
        Dim status As Integer
        <VBFixedStringAttribute(10)> Public cmd As String
    End Structure

    Public Function SerializeObject(ByVal What As Object) As Byte()
        Dim MemStream As New MemoryStream
        Dim BinWriter As New BinaryWriter(MemStream)
        Dim BinFormatter As New BinaryFormatter
        BinFormatter.Serialize(BinWriter.BaseStream, What)
        BinWriter.Close()
        Return MemStream.ToArray
    End Function


            Dim sp As my_protocol = New my_protocol
            sp.type = 2
            sp.cmd = "pc1" + Chr(0)

            stream.Write(SerializeObject(sp), 0, 12)
            stream.Flush()

warum erhalte ich im C-Programm für den type 256 statt 2?
die C Struktur: int int char[10]

Gruß
paule
 

sheel

I love Asm
Hi

hast du dir mal angeschaut, was in C ankommt?
Mit dem Binaryformatter ist man da komplett daneben.
Der speichert Sachen wie Klassennamen etc. auch mit,
und das C-Programm kann damit natürlich nichts anfangen.

Behandle die drei Variablen einzeln.
Ints kann man mit BitConverter zu Bytearrays umwandeln
Für Strings soltle mit der Klasse Encoding etc. was zu machen sein.
Dann die puren Byte schicken.
 

jkallup

Erfahrenes Mitglied
Hallo sheel,

das geht natürlich auch. Allerdings habe ich feststellen müssen, das Daten
zum Beispiel integer 16 nicht als 00 00 00 0f sondern als 10 übertragen werden.
kann man da was machen?

Achja, ich bräuchte auch noch Starthilfe für einen linux C server, der auf eingehende
Daten idelt. so wie das der Apache auch macht hier der code den ich schonmal habe:

Code:
#ifndef __GLOBALS_H__
#define __GLOBALS_H__

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <dirent.h>
#include <time.h>
#include <poll.h>
#include <errno.h>
#include <signal.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <limits.h>
#include <stdarg.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <pthread.h>

#define SERVER_PORT 1001

#define MOD_CONN_TCP 1
#define MOD_CONN_UDP 2

#define true 1
#define false 0
typedef short bool;

struct server_module
{
    int 	type;
    char	desc[16];
    void	(*handler)();
    int 	(*init)();
    int 	(*recv)();
};

struct server_client
{
    int 		type;
    struct in_addr	ip;
    int 		port;
    bool		connected;
    bool		conn_flag;
    time_t		login;
    time_t		expire;
};

extern struct server_client *client[];
extern int con_idx;

struct nt_protocol
{
    char  type[5];  // sollte int sein
    char  status[5]; // dito
    char cmd[10];
};

#endif




#include "globals.h"

#define MAX_CONNECTIONS 256

int con_idx = 0;
struct server_client *client[256];

static fd_set master;
static fd_set read_fds;

int check_for_disconnect(int s)
{
    int i;
    for (i = 0; i < MAX_CONNECTIONS; i++)
    {
	if (i == s)
	{
	    char buf[200];
	    strcpy(buf, "ServerSide disconnect");

            if ((send(s, buf, strlen(buf), 0)) == -1)
		printf("Server: send() data to: %s error,\n",
		(client[i]->ip.s_addr));

	    close(s);
	    FD_CLR(i, &master);
	    --con_idx;

	    client[s]->connected = false;
            break;
	}
    }
}

char *trim(char *str)
{
    char ptr[strlen(str)+1];
    int i, j = 0;

    for (i = 0; str[i] != '\0'; i++)
    {
	if (str[i] != ' ' && str[i] != '\t')
	ptr[j++] = str[i];
    }

    ptr[j] = '\0';
    str = ptr;
}

int main()
{
    int yes = 1;
    int fdmax;
    int newfd;
    int nbytes;

    char buf[1024];
    int i;

    for (i = 0; i < MAX_CONNECTIONS; i++)
    {
	client[i] = (struct server_client*) malloc(sizeof(struct server_client)+1);
        client[i]->type = 0;
	client[i]->connected = false;
    }

    FD_ZERO(&master);
    FD_ZERO(&read_fds);

    int listener;

    if ((listener = socket(AF_INET, SOCK_STREAM, 0)) == -1)
    {
        exit(1);
    }
    else {
        printf("Server: socket() is OK!\n");
    }

    if (setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1)
    {
        perror("Server: socket() error.");
        exit(1);
    }
    printf("Server: setsockopt() is Ok...\n");

    struct sockaddr_in service;
    struct sockaddr_in clientaddr;

    service.sin_family = AF_INET;
    service.sin_addr.s_addr = INADDR_ANY; //inet_addr("192.168.178.79");
    service.sin_port = htons(SERVER_PORT);
    memset(&(service.sin_zero),'\0', 8);

    if (bind(listener, (struct sockaddr*)&service, sizeof(service)) == -1)
    {
	printf("Server: bind() failed:\n");
        exit(1);
    }
    printf("Server: bind() is OK!\n");

    if (listen(listener, 10) == -1)
    {
        printf("Server: listen(): Error listening on socket\n");
	exit(1);
    }
    printf("Server: listen() is OK, I'm waiting for connections...\n");

    FD_SET(listener, &master);
    fdmax = listener;

    int addrlen;

    for (;;)
    {
        read_fds = master;
	if(select(fdmax+1, &read_fds, NULL, NULL, NULL) == -1)
	{
	    perror("Server-select() error lol!");
	    exit(1);
	}
        printf("Server-select() is OK...\n");

	labse:
	i = 0;
        for (i = 0; i <= fdmax; i++)
	{
	    if (FD_ISSET(i, &read_fds))
	    {
		if (i == listener)
		{
		    addrlen = sizeof(clientaddr);
		    if ((newfd = accept(listener, (struct sockaddr *)&clientaddr, &addrlen)) == -1)
		    {
			perror("Server: accept() error.");
			exit(1);
		    }
		    else
		    {
		    	printf("Server: accept() is Ok...\n");

		    	FD_SET(newfd, &master);
			if (newfd > fdmax)
			fdmax = newfd;

			printf("new connection from: %s on socket: %d\n",
			inet_ntoa(clientaddr.sin_addr), newfd);

			client[newfd]->ip   = clientaddr.sin_addr;
			client[newfd]->port = SERVER_PORT;
			client[newfd]->connected = true;
			client[newfd]->conn_flag = false;

			con_idx++;

			char buf[200];

			if (con_idx > 4)
			{
				sprintf(buf,
				"Fehler:\n"
				"Maximale Verbindungsanzahl erreicht!");

				send(newfd, buf, strlen(buf), 0);
				printf("Server: max connection reached.\n");
			}
			else {
				sprintf(buf,
				"      Willkommen auf den CS-Server\n"
				"Copyright (c) 2012 by paulemh & paule22");

				if (send(newfd, buf, strlen(buf), 0) == -1)
				{
					printf("Client: can't send data.\n");
					close(newfd);
				}
			}

			printf("send to client ok.\n");
			break;
		    }
		}
		else
		{
		    struct nt_protocol *mp = (struct nt_protocol*) malloc(sizeof(struct nt_protocol));;
		    char field1[4];
		    char field2[4];
		    char field3[10];
		    int n1,n2,n3;

/*
		    if ((n1 = recv(i,(char*)field1,4,0)) == -1)
		    {
                        if (n1 == 0)
		        printf("socket: %d hang up\n",i);
		    	else
			perror("Server: recv() error!");

		    	close(i);
			close(newfd);
		    	FD_CLR(i, &master);
			--con_idx;
			break;
		    }
		    if ((n2 = recv(i,(char*)field1,4,0)) == -1)
		    {
                        if (n2 == 0)
		        printf("socket: %d hang up\n",i);
		    	else
			perror("Server: recv() error!");

		    	close(i);
			close(newfd);
		    	FD_CLR(i, &master);
			--con_idx;
			break;
		    }

		    if ((n3 = recv(i,(char*)field1,10,0)) == -1)
		    {
                        if (n1 == 0)
		        printf("socket: %d hang up\n",i);
		    	else
			perror("Server: recv() error!");

		    	close(i);
			close(newfd);
		    	FD_CLR(i, &master);
			--con_idx;
			break;
		    }

		    strcpy(mp->type,field1);
		    strcpy(mp->status,field2);
		    strcpy(mp->cmd,trim(field3));
*/

		    if ((nbytes = recv(i, (struct nt_protocol*)mp, sizeof(struct nt_protocol), 0)) <= 0)
		    {
			if (nbytes == 0)
		        printf("socket: %d hang up\n",i);
		    	else
			perror("Server: recv() error!");

		    	close(i);
			close(newfd);
		    	FD_CLR(i, &master);
			--con_idx;
			break;
		    }
		    else
		    {
			if (!strcmp(mp->cmd,trim("pc1")))
			{
				DIR *dir;
				struct dirent *ent;
				
				dir = opendir("/");
				if (dir != NULL)
				{
					char *dbs = malloc(4096);
					strcpy(dbs,"");

					while ((ent = readdir(dir)) != NULL)
					{
						if ((strstr(ent->d_name,"..") == NULL )
						|| ((strstr(ent->d_name,"." ) == NULL) && (strlen(ent->d_name) == 1))) {
						sprintf(buf,"%s\n",ent->d_name);
						strcat(dbs,buf); }
					}

					if ((send(newfd, dbs, strlen(dbs), 0)) == -1)
					printf("Server: send() data to: %s error,\n",
				   	inet_ntoa(clientaddr.sin_addr));

					free(dbs);
				}
				else {
					perror("error open");
				}

			} else if (!strcmp(mp->cmd,"pc2"))
			{
				printf("--> pc2 command\n");
			}

			int j;
			for (j = 0; j <= fdmax; j++)
			{
			    if (FD_ISSET(j, &master))
			    {
				if (j != listener && j == i)
				{
				    if (client[j]->conn_flag == true)
				    check_for_disconnect(j);
				    break;
				}
			    }
			}
		    }
		}
	    }
	}
    }

    return 0;
}

Gruß
paule
 

sheel

I love Asm
Allerdings habe ich feststellen müssen, das Daten
zum Beispiel integer 16 nicht als 00 00 00 0f sondern als 10 übertragen werden.
kann man da was machen?
Was meinst du?
Die Zahl 16 ist hexadezimal 10, nicht 0f.


Achja, ich bräuchte auch noch Starthilfe für einen linux C server, der auf eingehende
Daten idelt. so wie das der Apache auch macht hier der code den ich schonmal habe:
Wieso Starthilfe?
Über den Start scheinst du schon hinaus zu sein :D
Nur, was geht genau nicht?
 

jkallup

Erfahrenes Mitglied
es werden keine binär daten übermittelt, zb. 0x0F als 0F anstelle von char 0f.
musst dir nur mal eine datei ansehen mit nen hexeditor da weisst du was ich meine
 

jkallup

Erfahrenes Mitglied
also ich meinte, die daten so zu senden, wie sie im speicher repräsentiert werden. als zum beispiel 04050ff88
 

jkallup

Erfahrenes Mitglied
danke für den Tipp
ich dachte der server sollte die speicherrepräsentation der c type zu füttern bekommen
also z.b decimal 10 zu hex 0x0a
nur das 0a nicht als string, sondern als char zurückbekomm - 0a und bei int32 00000a
wenn du nen tipp hast immer her mit.
ansonsten teste ich das mal
 

sheel

I love Asm
Ja genau das mein ich doch.
Es wäre kompletter Unsinn, das als String zu machen
(langsamer, mehr Speicherverbrauch, auf C-Seite umständlicher...).

Beim Bitconverter bekommst du ja auch keinen String, sondern ein Bytearray.
Genau das brauchst du.