socket and sdl

Jul 15, 2014 at 5:04pm
i'm trying to run the method translate() on my application main loop, and my game pause until the server send a message back.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
//=============================================================================
#include "CRPGSockCli.h"
#include "CApp.h"
//=============================================================================
CRPGSockCli::CRPGSockCli() {
}

//=============================================================================
int CRPGSockCli::OnConnect()
{

    
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) 
    {
        perror("ERROR opening socket");
        exit(1);
    }
    

    bzero((char *) &serv_addr, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(portno);
serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    
         
  

    /* Now connect to the server */


connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));	
    /* Now ask for a message from the user, this message
    * will be read by server
    */
    
    return 0;



}
void CRPGSockCli::MoveUp()
{
strcpy(sndtxt, "mvup");

	/* Send message to the server */    
    n = write(sockfd,sndtxt,strlen(sndtxt));
    if (n < 0) 
    {
         perror("ERROR writing to socket");
         exit(1);
    }
    /* Now read server response */
    
    n = read(sockfd,rcvtxt,255);
    if (n < 0) 
    {
         perror("ERROR reading from socket");
         exit(1);
    }
    printf("%s\n",rcvtxt);

}
void CRPGSockCli::MoveDown()
{
strcpy(sndtxt, "mvdown");

	/* Send message to the server */    
    n = write(sockfd,sndtxt,strlen(sndtxt));
    if (n < 0) 
    {
         perror("ERROR writing to socket");
         exit(1);
    }
    /* Now read server response */
    
    n = read(sockfd,rcvtxt,255);
    if (n < 0) 
    {
         perror("ERROR reading from socket");
         exit(1);
    }
    printf("%s\n",rcvtxt);

}
void CRPGSockCli::MoveLeft()
{
strcpy(sndtxt, "mvleft");

	/* Send message to the server */    
    n = write(sockfd,sndtxt,strlen(sndtxt));
    if (n < 0) 
    {
         perror("ERROR writing to socket");
         exit(1);
    }
    /* Now read server response */
    
    n = read(sockfd,rcvtxt,255);
    if (n < 0) 
    {
         perror("ERROR reading from socket");
         exit(1);
    }
    printf("%s\n",rcvtxt);

}
void CRPGSockCli::MoveRight()
{
strcpy(sndtxt, "mvright");

	/* Send message to the server */    
    n = write(sockfd,sndtxt,strlen(sndtxt));
    if (n < 0) 
    {
         perror("ERROR writing to socket");
         exit(1);
    }
    /* Now read server response */
 
    n = read(sockfd,rcvtxt,255);
    if (n < 0) 
    {
         perror("ERROR reading from socket");
         exit(1);
    }
    printf("%s\n",rcvtxt);

}
int CRPGSockCli::Translate
{

    /* Now read server response */
    
    n = read(sockfd,rcvtxt,255);
    
    

}
Last edited on Jul 15, 2014 at 5:30pm
Jul 16, 2014 at 8:55am
That's because your read is blocking. And while you're at it, there's no reason to hang around waiting for the writes to complete either. There are several methods for dealing with this, but the basic problem is that you're not interested in waiting for a client to send you something.

You can hand off the wait to a different thread. That thread can notify the main thread (with a flag) that a message is available to be processes, where it can then just be pulled from a shared container.

You can use the Reactor Pattern. You use select (or epoll or kqueue or Completion Ports) to determine if the socket is available for read. Only then do you read it.

You can use the Proactor Pattern. This is using ASIO to call you when something interesting happens (like a client sending you a request).

Using select is your easiest solution to use. There's an example here:
http://beej.us/guide/bgnet/examples/select.c

The reference text is here:
http://www.beej.us/guide/bgnet/output/html/multipage/advanced.html

So Translate becomes:
1
2
3
4
5
6
7
8
9
10
11
12
13
int CRPGSockCli::Translate()
{
    fd_set readfds;
    FD_ZERO(&set readfds);
    FD_SET(sockfd, &readfds);
    struct timeval tv  = { 0, 0 };
    select(sockfd + 1, &readfds, NULL, NULL, &tv);
    if (FD_ISSET(sockfd))
    {
        // a client wrote a message, let's read it
        n = read(sockfd, rcvtxt, 255);
    }
}
Last edited on Jul 16, 2014 at 10:13am
Jul 16, 2014 at 10:09am
Tell me how it should be using sdl_net, because i changed here before you sent the message
CRPGSockCli.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
//=============================================================================
#include "CRPGSockCli.h"
#include "CApp.h"
//=============================================================================
CRPGSockCli::CRPGSockCli() {
}

//=============================================================================
int CRPGSockCli::OnConnect()
{
SDLNet_Init();
SDLNet_ResolveHost(&ip,"127.0.0.1",9999);

sd = SDLNet_TCP_Open(&ip);
//const char* t="aaaaaaaaaaaaaaa";
//strcpy(sndtxt, "aaaaaaaaaaaaaa");   
//SDLNet_TCP_Send(sd,sndtxt,strlen(t)+1);
bool reading =true;
while (reading==true){  
SDLNet_TCP_Recv(sd,rcvtxt,strlen(rcvtxt));
printf(rcvtxt);
}}
void CRPGSockCli::MoveUp()
{
strcpy(sndtxt, "mvup");
SDLNet_TCP_Send(sd,sndtxt,strlen(sndtxt)+1); 

}
void CRPGSockCli::MoveDown()
{
strcpy(sndtxt, "mvdown");
SDLNet_TCP_Send(sd,sndtxt,strlen(sndtxt)+1); 
}
void CRPGSockCli::MoveLeft()
{
strcpy(sndtxt, "mvleft");
SDLNet_TCP_Send(sd,sndtxt,strlen(sndtxt)+1); 
}
void CRPGSockCli::MoveRight()
{
strcpy(sndtxt, "mvright");
SDLNet_TCP_Send(sd,sndtxt,strlen(sndtxt)+1); 
}
int CRPGSockCli::Translate()
{
//SDLNet_TCP_Recv(sd,rcvtxt,strlen(rcvtxt));
}
//-----------------------------------------------------------------------------

//=========================================================

CRPGSockCli.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
//=============================================================================
//=============================================================================
#ifndef _CRPGSOCKCLI_H_
#define _CRPGSOCKCLI_H_
#include <stdio.h>
#include <sys/types.h> 
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "CRPGSockCli.h"
#include <vector>
#include <SDL2/SDL.h>
#include <SDL2/SDL_ttf.h>
#include "SDL/SDL_net.h"
#include <iostream>
#include <sstream>
#include <cstring>
//=============================================================================
class CRPGSockCli  {
struct sockaddr_in serv_addr;
    public:

    int sockfd,  n;
    
	TCPsocket sd, csd; /* Socket descriptor, Client socket descriptor */
	IPaddress ip, *remoteIP;
	
	char buffer[512];  

char sndtxt[256];
char rcvtxt[256];
char username[256];;
char password[256];
int portno = 9999;

    CRPGSockCli();
public:
    int OnConnect(); 
void MoveRight();
void MoveLeft();
void MoveUp();
void MoveDown();
int Translate();
};

//=============================================================================

#endif 
Last edited on Jul 16, 2014 at 10:43am
Jul 16, 2014 at 12:26pm
TCPsocket sd, csd;


1
2
3
4
5
6
int CRPGSockCli::OnConnect()
{

SDLNet_Init();
fcntl(sd, F_SETFL, O_NONBLOCK);
SDLNet_ResolveHost(&ip,"127.0.0.1",9999);


CRPGSockCli.cpp:13:30: error: invalid conversion from ‘TCPsocket {aka _TCPsocket*}’ to ‘int’ [-fpermissive]
fcntl(sd, F_SETFL, O_NONBLOCK);
Last edited on Jul 16, 2014 at 12:27pm
Jul 16, 2014 at 1:33pm
Don't use non-blocking sockets. You can't just make that change without dealing with how you call read/write.

I haven't used SDL, but as far as I can tell, you need to use:
SDLNet_CheckSockets
SDLNet_SocketReady
Last edited on Jul 16, 2014 at 1:34pm
Jul 16, 2014 at 5:23pm
Application running correctly now, thanks.
Topic archived. No new replies allowed.