0

メッセージを小文字または大文字でサーバーに送信する UDP クライアント/サーバーがあります。サーバーはメッセージを受信し、大文字と小文字を切り替えて中継します。サーバーがそれを最初のクライアントにリレーして戻す代わりに、クライアント2に送信する代わりに、どうすればよいかわかりません。私のclient2がメッセージを送信すると、サーバーはそれを受信して​​client2に送り返し、client1でも同じことをします。私はclient1がサーバーに送信し、サーバーがそれをclient2に送信することを望んでいます。考えられることはすべて試しましたが、わかりません。

サーバ:

/*
Simple udp server

*/
#include<stdio.h>   //printf
#include<string.h> //memset
#include<stdlib.h> //exit(0);
#include<arpa/inet.h>
#include<sys/socket.h>
#include<ctype.h>

#define BUFLEN 512  //Max length of buffer
#define PORT 8888   //The port on which to listen for incoming data

void die(char *s)
{
    perror(s);
exit(1);
}

int main(void)
{
struct sockaddr_in si_me, si_other, si_other2;

int s, i, slen = sizeof(si_other) , recv_len;
char buf[BUFLEN];

//create a UDP socket
if ((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
{
    die("socket");
}

// zero out the structure
memset((char *) &si_me, 0, sizeof(si_me));

si_me.sin_family = AF_INET;
si_me.sin_port = htons(PORT);
si_me.sin_addr.s_addr = htonl(INADDR_ANY);

//bind socket to port
if( bind(s , (struct sockaddr*)&si_me, sizeof(si_me) ) == -1)
{
    die("bind");
}

//keep listening for data
while(1)
{
    printf("Waiting for data...");
    fflush(stdout);

    //try to receive some data, this is a blocking call
    if ((recv_len = recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *) &si_other, &slen)) == -1)   // read datagram from server socket
    {
        die("recvfrom()");
    }

    //print details of the client/peer and the data received
    printf("Received packet from %s:%d\n", inet_ntoa(si_other.sin_addr), ntohs(si_other.sin_port));         printf("Data: %s\n" , buf);

    //now reply to server socket/the client with the same data
    if (sendto(s, buf, recv_len, 0, (struct sockaddr*) &si_other, slen) == -1)
    {
        die("sendto()");
    }



}

close(s);
return 0;
}

クライアント:

/*
Simple udp client

*/
#include<stdio.h>   //printf
#include<string.h> //memset
#include<stdlib.h> //exit(0);
#include<arpa/inet.h>
#include<sys/socket.h>
#include<ctype.h>

#define SERVER "192.x.x.x"
#define BUFLEN 512  //Max length of buffer
#define PORT 8888   //The port on which to send data

void die(char *s)
{
perror(s);
exit(1);
}

int main(void)
{
struct sockaddr_in si_other;
int s, s2, i, slen=sizeof(si_other);
char buf[BUFLEN];
char message[BUFLEN];

if ( (s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)        // create a client socket
{
    die("socket");
}

memset((char *) &si_other, 0, sizeof(si_other));
si_other.sin_family = AF_INET;
si_other.sin_port = htons(PORT);

if (inet_aton(SERVER , &si_other.sin_addr) == 0)            // Create datagram with server IP and port.
{
    fprintf(stderr, "inet_aton() failed\n");
    exit(1);
}

while(1)
{
    printf("Enter message : ");
    gets(message);


    int a;
    char message2[BUFLEN];
    for(a=0;a<=BUFLEN-1;a++)
      {
        if(message[a] >= 97 && message[a] <= 122)
           message2[a] = toupper(message[a]);
        else
           message2[a] = tolower(message[a]);

      }


    if (sendto(s, message2, strlen(message2) , 0 , (struct sockaddr *) &si_other, slen)==-1)
    {
        die("sendto()");
    }


    //receive a reply and print it
    //clear the buffer by filling null, it might have previously received data
    memset(buf,'\0', BUFLEN);
    //try to receive some data, this is a blocking call
    if (recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *) &si_other, &slen) == -1)        // read datagram from client socket
    {
        die("recvfrom()");
    }

    puts(buf);
}

close(s);
return 0;
}
4

2 に答える 2

1

あなたread()またはrecvfrom()あなたのメッセージの後、あなたはあなたのデータを処理し、次にsendto()2回処理します:1つは(元の送信者)によって返されたアドレスに、もう1つrecvfrom()は他のクライアントのアドレス(サーバーによって何らかの方法で提供または検出される必要があります)に送信されます。

これに沿った何か(適切なエラーチェックが実行されていない):

char data[100];
struct sockaddr_in address;
socklen_t length = sizeof address;

/* Receive data from any client. */
ssize_t result = recvfrom(server, data, sizeof data, 0, &address, &length);

/* Process the data (change cases). */
process_data(data, result);

/* Send back to the first client. */
sendto(server, data, result, 0, &address, sizeof address);

/* Check who's the sender and relay to the other. */
if (address.sin_addr.s_addr == CLIENT1_ADDRESS)
    address.sin_addr.s_addr = CLIENT2_ADDRESS;
else
    address.sin_addr.s_addr = CLIENT1_ADDRESS;

/* Send to the other client. */
sendto(server, data, result, 0, &address, sizeof address);

この例では、アドレスは静的に定義されています。

于 2013-02-24T23:21:39.583 に答える
1

UDP サーバーの代わりに、client->server->client2 からのようなパケットのフォワーダーが必要なようです。そのため、サーバーに client2 の IP アドレス/ポートを伝える必要があります。コマンドライン引数を使用するか、任意の入力ファイルを読み取り、サーバー コードの sendto ステートメントの前に、コマンド ラインまたは入力ファイルからの teken として client2 情報を si_other 構造体に入力します。

于 2013-02-24T18:51:01.910 に答える