2012-05-09 74 views
-3

我似乎無法弄清楚如何在我現有的套接字之間發送和接收數據。現在我只是試着來回發送一個字符串,並能夠看到它。對於我做錯什麼的任何幫助將不勝感激。c中的客戶端和服務器套接字

問題部分在這裏:

char hostm[10]; 
    printw("you are host!\n"); 
    printw("Type the number you would like to pick %s: ", req.hostname);//gets row1 
    scanw("%s", &hostm); 
    printw("%s\n", hostm); 

       write((struct sockaddr *)&req.sa, &hostm, sizeof(hostm)); 
       char response[80]; 
       read((struct sockaddr *)&resp.sa, &response, sizeof(response)); 

       printw("Response: %s\n", response); 
    recvfrom(sock, (void *)&resp, sizeof (matchrequest), 0, (struct sockaddr *)&sa, &fromlen); 

 char response[80]; 
char response2[80]; 
read((struct sockaddr *) &host.sa, &response, sizeof(response)); 
read((struct sockaddr *) &req.sa, &response2, sizeof(response2)); 
printf("\n\nresponse was %s\n%s\n", &response, &response2); 
     write((struct sockaddr *) &req.sa, &response, sizeof(response)); 
write((struct sockaddr *) &host.sa, &response2, sizeof(response2)); 

我不知道,如果它在正確的地方要麼,所以這裏是所有代碼:

同行.c

#include <ncurses.h> 
#include <stdlib.h> 
#include <stdio.h> 
#include <errno.h> 
#include <string.h> 
#include <sys/socket.h> 
#include <sys/types.h> 
#include <netinet/in.h> 
#include <unistd.h> 
#include <arpa/inet.h> 
#include <pthread.h> 
#include "match.h" 

int sock; 
struct sockaddr_in serveraddr; 
matchrequest req; 
int matched = 0; 

void *thread_start(void *args) { 
int bytes_sent; 
while(!matched) { 
    printf("waiting for peers...\n"); 
    bytes_sent = sendto(sock, &req, sizeof(matchrequest), 0,(struct sockaddr*)&serveraddr, sizeof serveraddr); 
    if (bytes_sent < 0) { 
     printf("Error sending packet: %s\n", strerror(errno)); 
     exit(EXIT_FAILURE); 
    } 
    sleep(3); 
} 
} 
void writeResponse(char * response) { 
write(sock, &response, sizeof(response)); 
} 

int main(int argc, char *argv[]) 
{ 
pthread_t th; 
struct sockaddr_in sa; 

matchrequest resp; 
ssize_t recsize; 
socklen_t fromlen; 


sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); 

if (argc != 3) { 
    printf("specify name and game type for this peer!\n"); 
    return; 
} 

req.gametype = atoi(argv[2]); 
req.state = 0; 
strncpy(req.peername, argv[1], 100); 

printf("using name: %s\n", req.peername); 

memset(&sa, 0, sizeof sa); 
sa.sin_family = AF_INET; 
sa.sin_addr.s_addr = INADDR_ANY; 
sa.sin_port = 0; 

if (-1 == bind(sock,(struct sockaddr *) &sa, sizeof(sa))) 
{ 
     perror("error bind failed"); 
     close(sock); 
     exit(EXIT_FAILURE); 
} 

memset(&serveraddr, 0, sizeof serveraddr); 
serveraddr.sin_family = AF_INET; 
serveraddr.sin_addr.s_addr = inet_addr("127.0.0.1"); 
serveraddr.sin_port = htons(7652); 
pthread_create(&th, NULL, &thread_start, NULL); 

for (;;) 
{ 
    fromlen = sizeof(sa); 
     recsize = recvfrom(sock, (void *)&resp, sizeof (matchrequest), 0, (struct sockaddr *)&sa, &fromlen); 
     if (recsize < 0) { 
      fprintf(stderr, "%s\n", strerror(errno)); 
      exit(EXIT_FAILURE); 
     } 
    if (recsize != sizeof(matchrequest)) { 
     fprintf(stderr, "invalid datagram received"); 
     continue; 
    } 


    initscr(); 
     printw("matched with peer %s. Game can start!\n", resp.peername); 

    if(strcmp(resp.hostname, req.peername) == 0) 
    { 

     char hostm[10]; 
     printw("you are host!\n"); 
     printw("Type the number you would like to pick %s: ", req.hostname);//gets row1 
     scanw("%s", &hostm); 
     printw("%s\n", hostm); 

        write((struct sockaddr *)&req.sa, &hostm, sizeof(hostm)); 
        char response[80]; 
        read((struct sockaddr *)&resp.sa, &response, sizeof(response)); 

        printw("Response: %s\n", response); 
     recvfrom(sock, (void *)&resp, sizeof (matchrequest), 0, (struct sockaddr *)&sa, &fromlen); 


    } 
    else 
    { 
     char peerm[10]; 
        printw("you are peer!\n"); 
        printw("Type the number you would like to pick %s: ", req.peername);//gets row1 
        scanw("%s", &peerm); 
        printw("%s\n", &peerm); 

        // send to client, transmitted fine 
        write(sock, &peerm, sizeof(peerm)); 
        char response[80]; 
        read(sock, &response, sizeof(response)); 
        // Prints the missing character symbol, and 'random' letters 
        printw("Response: %s\n", response); 

    } 
    endwin(); 
} 
close(sock); /* close the socket */ 
return 0; 
} 

matchd .C

#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <arpa/inet.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <unistd.h> 
#include <errno.h> 
#include "match.h" 

#define MAX_REQUESTS 100 

matchrequest ready[MAX_REQUESTS]; 
int outsock; 

void handlerequest(struct sockaddr_in sa, matchrequest req) { 

matchrequest host; 
int idx = req.gametype % MAX_REQUESTS; 

req.state = READY; 
req.sa = sa; 

printf("%s on %s:%d requested game type %d \n", req.peername, inet_ntoa(req.sa.sin_addr), req.sa.sin_port, req.gametype); 

// if room, place in ready position 
if (strncmp(ready[idx].peername, req.peername, 100) == 0) { 
    // peer is just checking in 
} else if (ready[idx].state == MATCHED) { 
    ready[idx] = req; 
    printf("%s selected as host. waiting for peers...\n", req.peername); 
    strcpy(req.hostname, req.peername); 
} else { 
// match with existing peer 
    printf("%s matched with existing host\n", req.peername); 
    req.state = MATCHED; 
    host = ready[idx]; 
    host.state = HOST; 
    ready[idx] = req; 
    strcpy(req.hostname, host.peername); 
    req.peermove = req.hostmove; 
    req.hostmove = req.peermove; 

    char response[80]; 
    char response2[80]; 
    read((struct sockaddr *) &host.sa, &response, sizeof(response)); 
    read((struct sockaddr *) &req.sa, &response2, sizeof(response2)); 
    printf("\n\nresponse was %s\n%s\n", &response, &response2); 
      write((struct sockaddr *) &req.sa, &response, sizeof(response)); 
    write((struct sockaddr *) &host.sa, &response2, sizeof(response2)); 

//  read(outsock, &response, sizeof(response)); 
//  printf("\n\nresponse was %s\n\n", &response); 
//  write(outsock, &response, sizeof(response)); 


    printf("sending response to %s at %s:%d\n", host.peername, inet_ntoa(host.sa.sin_addr), host.sa.sin_port); 
    sendto(outsock, (void *) &req, sizeof(matchrequest), 0, (struct sockaddr *) &host.sa, sizeof(host.sa)); 
    printf("sending response to %s at %s:%d\n", req.peername, inet_ntoa(req.sa.sin_addr), req.sa.sin_port); 
    sendto(outsock, (void *) &host, sizeof(matchrequest), 0, (struct sockaddr *) &req.sa, sizeof(req.sa)); 
     fprintf(stderr, "%s\n", strerror(errno)); 
} 
} 

int main(void) 
{ 
int sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); 
struct sockaddr_in sa; 
matchrequest req; 
ssize_t recsize; 
socklen_t fromlen; 

outsock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); 

memset(&sa, 0, sizeof sa); 
sa.sin_family = AF_INET; 
sa.sin_addr.s_addr = INADDR_ANY; 
sa.sin_port = htons(7652); 

if (-1 == bind(sock,(struct sockaddr *)&sa, sizeof(sa))) 
{ 
     perror("error bind failed"); 
     close(sock); 
     exit(EXIT_FAILURE); 
} 
for (;;) 
{ 
    fromlen = sizeof(sa); 
     printf ("receiving....\n"); 

     recsize = recvfrom(sock, (void *)&req, sizeof (matchrequest), 0, (struct sockaddr *)&sa, &fromlen); 
     if (recsize < 0) { 
      fprintf(stderr, "%s\n", strerror(errno)); 
      exit(EXIT_FAILURE); 
     } 
    if (recsize != sizeof(matchrequest)) { 
     fprintf(stderr, "invalid datagram received"); 
     continue; 
    } 
    handlerequest(sa, req); 
} 
} 

match.h

#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <arpa/inet.h> 

typedef enum matchstate {MATCHED = 0, READY, HOST} matchstate; 

typedef struct matchrequest { 
    matchstate state; 
    int gametype; 
    char board[4][4]; 
    char covboard[4][4]; 
    int player1pts; 
    int player2pts; 
    int gameover; 
    int turn; 
    int hostmove; 
    int peermove; 
    char peername[100]; 
    char hostname[100]; 
    struct sockaddr_in sa; 
} matchrequest; 
+2

嘗試將您的問題縮小到10-20行代碼。 –

+1

http://stackoverflow.com/questions/10412264/how-to-send-info-across-berkeley-sockets *嘆息* – Trevor

+0

分析代碼和發現問題需要很長時間。你最好的辦法是使它非常簡單的客戶端服務器測試應用程序,然後問,如果你仍然無法找到問題。在有人花時間在這之前,這一個對於賞金是有好處的。 – AvkashChauhan

回答

0

我認爲這個問題是readwrite期待文件描述符作爲第一個參數,但你完全別的東西提供。請參閱write的文檔,並注意您不會按照您應該的方式調用它。另外,我沒有閱讀你的所有代碼,但它看起來好像會產生很多你不應忽視的警告。

另請注意,read可能會過早返回,或者可能會在等待更多數據到達時阻止。你必須自己照顧這些情況。

另外,請記住,與TCP不同,不能保證或確認數據的傳送。因此,雖然您的程序已經發送了數據,但可能會在傳輸給客戶端時丟失。

+0

謝謝,我會嘗試。 –

相關問題