socket and sdl

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
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
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
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
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
Application running correctly now, thanks.
Topic archived. No new replies allowed.