forums.ps2dev.org Forum Index forums.ps2dev.org
Homebrew PS2, PSP & PS3 Development Discussions
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

UDP Socket - How to tell when it's ready.

 
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development
View previous topic :: View next topic  
Author Message
lgnr



Joined: 17 Dec 2009
Posts: 39

PostPosted: Fri Jul 02, 2010 11:02 pm    Post subject: UDP Socket - How to tell when it's ready. Reply with quote

Apparently I'm experiencing some strange behavior.
I can connect to my wifi network. But when I run:

mainsock = socket(AF_INET, SOCK_DGRAM, 0);

My app seems to take about 20 seconds to send the first packet that the server receives right, but before that the call:

sendto() returns values > 1, so I can't really check when the socket is ready. I just know that because the wireless LED on the PSP starts to flash quicker when it's ready.

Any solution for that? Am I starting something wrong or that delay is expected? Also, can I call anything like GetInfo() to check the state? Since i can't really check if sendto > 1, which is returning true since the beginning.
Or should I run another thread and wait for the handshaking from the server?

Thanks in advance!
Back to top
View user's profile Send private message
lgnr



Joined: 17 Dec 2009
Posts: 39

PostPosted: Sat Jul 03, 2010 4:36 am    Post subject: Reply with quote

I mean, is it a good idea to run a client and a server on different threads?
Back to top
View user's profile Send private message
jimparis



Joined: 10 Jun 2005
Posts: 1179
Location: Boston

PostPosted: Wed Jul 07, 2010 6:11 am    Post subject: Reply with quote

Is it waiting for a DHCP response or something? Maybe it's associated with the access point but hasn't gotten an address yet. Are you waiting for that?
Back to top
View user's profile Send private message
lgnr



Joined: 17 Dec 2009
Posts: 39

PostPosted: Wed Jul 07, 2010 6:32 am    Post subject: Reply with quote

Sorry for the other post. I've completely forgotten.
Thanks for the reply. I'm just connecting using the 'standard' function found on the samples:

Code:

int connect_to_apctl(int config)
{
   int err;
   int stateLast = -1;

   /* Connect using the first profile */
   err = sceNetApctlConnect(config);
   if (err != 0)
   {
      printf(MODULE_NAME ": sceNetApctlConnect returns %08X\n", err);
      return 0;
   }

   printf(MODULE_NAME ": Connecting...\n");
   while (1)
   {
      int state;
      err = sceNetApctlGetState(&state);
      if (err != 0)
      {
         printf(MODULE_NAME ": sceNetApctlGetState returns $%x\n", err);
         break;
      }
      if (state > stateLast)
      {
         printf("  connection state %d of 4\n", state);
         stateLast = state;
      }
      if (state == 4)
         break;  // connected with static IP

      // wait a little before polling again
      sceKernelDelayThread(50*1000); // 50ms
   }
   printf(MODULE_NAME ": Connected!\n");

   if(err != 0)
   {
      return 0;
   }

   return 1;
}



Also, i found out that if i put the exact same code to run on a thread, it takes much more time (about 2~3 minutres).

Code:

while(running)
{
    error = sendto(sock,message,sizeof_message, 0, (struct sockaddr *)&address, sizeof(address));

   if(error < 0) printf("Error on sendto\n");

   sleep(100000);
}



It outputs "Error on sendto" for about 2~3 minutes and then starts to send right.


Thanks in advance.
Back to top
View user's profile Send private message
lgnr



Joined: 17 Dec 2009
Posts: 39

PostPosted: Wed Jul 07, 2010 6:47 am    Post subject: Reply with quote

Hm. Seems like DHCP can get a little tricky.
http://forums.ps2dev.org/viewtopic.php?t=3926&highlight=dhcp
I have already looked at the wifi_03 src, but i'm not very familiar with loading modules in kernel mode. All i did so far was writing some unix-like socket client/server.
But as now it's probably the only way, and since i know that could be my problem, i'll take a closer look.
Thanks :)
Back to top
View user's profile Send private message
lgnr



Joined: 17 Dec 2009
Posts: 39

PostPosted: Wed Jul 07, 2010 7:15 am    Post subject: Reply with quote

Strange thing is that PSP is receiving an ip and the router's log also shows that the ip was delivered, before the psp starts to print "Error on sendto". Weird.
Back to top
View user's profile Send private message
jimparis



Joined: 10 Jun 2005
Posts: 1179
Location: Boston

PostPosted: Thu Jul 08, 2010 7:19 am    Post subject: Reply with quote

When sendto returns an error, what error is it? Check errno.
Back to top
View user's profile Send private message
m0skit0



Joined: 02 Jun 2009
Posts: 226

PostPosted: Thu Jul 08, 2010 10:15 pm    Post subject: Reply with quote

Keep in mind UDP is a stateless, non-error correction protocol. Using it through CSMA/CA (Wifi low-level protocol) may yield to a lot of lost packets, so maybe that's your issue, specially on spaces with high interferences.

Also, there's no handshake with UDP protocol, unlike TCP. If the packet is received by the receptor, there's no acknowledgment sent to the sender. I suggest you using TCP instead, unless you really know what you're doing.
_________________
The Incredible Bill Gates wrote:
The obvious mathematical breakthrough would be development of an easy way to factor large prime numbers.
Back to top
View user's profile Send private message
lgnr



Joined: 17 Dec 2009
Posts: 39

PostPosted: Fri Aug 06, 2010 11:42 am    Post subject: Reply with quote

I have switched everything to run under user mode.
Using threads, the delay seems to be much bigger. It sounds nonsense but sometimes it takes about 2 minutes before it can send the first package right. After that, every packet arrives OK.
I am aware of how UDP works, but this is not a ploblem of losing data, because it takes too much time to send the first one, but after that everything works as expected.
Seems like a problem of modules loading or anything, but the curious thing is that it does work after this crazy delay.
This is tricky... I'm kinda loosing hope here.
Back to top
View user's profile Send private message
lgnr



Joined: 17 Dec 2009
Posts: 39

PostPosted: Fri Aug 06, 2010 11:47 am    Post subject: Reply with quote

I will change this to work with TCP, but I dont really like the method of changing things and not being able to tell what is wrong with the previous solution.
Thanks guys!
Back to top
View user's profile Send private message
lgnr



Joined: 17 Dec 2009
Posts: 39

PostPosted: Fri Aug 06, 2010 12:19 pm    Post subject: Reply with quote

Just so another people can check this out:

I was looking at the WiFi Controller source and came across this:

Code:

sock = sceNetInetSocket(AF_INET, SOCK_DGRAM, 0);
  if (sock < 0) {
    return -1;
  }

  err = sceNetInetConnect(sock, &addr, sizeof(addr));
  if (err) {
    return -1;
  }


Which means that altought it IS UDP socket, you can call connect() so you can use send() instead of sendto(). Am I right?
I was not using connect() at all. I will try that.
Back to top
View user's profile Send private message
lgnr



Joined: 17 Dec 2009
Posts: 39

PostPosted: Sat Aug 07, 2010 5:50 am    Post subject: Reply with quote

Possibly useful update:

I tested under 3 different routers (home, school lab, friend's house).
At home - takes ~ 2, 3 minutes to send first packet right. Tried more than 20 times.
At school - immediately works. Tried 7 times.
Friend's - takes 20 seconds. 5 times tested.

All 3 networks were set to DHPC, under same distance to router.
Back to top
View user's profile Send private message
m0skit0



Joined: 02 Jun 2009
Posts: 226

PostPosted: Sat Aug 07, 2010 8:30 am    Post subject: Reply with quote

If so, then it's a network-related problem on your house.
_________________
The Incredible Bill Gates wrote:
The obvious mathematical breakthrough would be development of an easy way to factor large prime numbers.
Back to top
View user's profile Send private message
lgnr



Joined: 17 Dec 2009
Posts: 39

PostPosted: Tue Aug 10, 2010 12:12 am    Post subject: Reply with quote

m0skit0 thanks for the patience with me.

I still can not fix this issue.
Maybe it is indeed a problem with my network, but what bugs me is that it DOES connect after some weird time, which in my modest opinion, should not happen if there was a (easy-solving) problem with my network.
How tricky! lol
Back to top
View user's profile Send private message
lgnr



Joined: 17 Dec 2009
Posts: 39

PostPosted: Tue Aug 10, 2010 12:29 am    Post subject: Reply with quote

By the way, this is being a huge learning experience for me. So I'm trying to keep this topic up-to-date to future readers.

I'm studying several sources found on the internet. Basically, my networking model is inspired on the PSP WiFi Controller v.0.4.4, which is easy to understand and much more simpler.
Now, taking a closer look at the PSPFTPd source, I got a little confused. It uses Net Lib Helper (nlh.h) to init, load drivers, connect etc. And also includes a socket layer (my_socket.h).

Now, I'm glad to say PSPFTPd works just fine and connects almost immediately to my network.

I know this is getting a little (too much) annoying for you guys, but I'm doing my best here.

So, does anyone knows what is the big difference between those two approaches? I mean, at first I tought PSPFTPd networking was beyound of what i needed, and a much simpler approach would do the trick.
Any toughts on that, anyone?

Thanks a lot.
Back to top
View user's profile Send private message
lgnr



Joined: 17 Dec 2009
Posts: 39

PostPosted: Tue Aug 10, 2010 6:19 am    Post subject: Reply with quote

Ok, i did some more testing at home:

Using WPA - Takes about 2 minutes to connect
Using WEP - Takes the same time
Without Encryption (Open network) - Connects emmediately.
Back to top
View user's profile Send private message
lgnr



Joined: 17 Dec 2009
Posts: 39

PostPosted: Tue Aug 10, 2010 8:42 am    Post subject: Reply with quote

Now my PSP is just messing with me.

I know when its working because the WIFI LED flashes quick.
When i enter the server IP 192.168.0.101 on the PSP, the LED starts flashing right away.
So thats it, with WPA on, It works immediately for this IP only. For all other addresses I have to wait about 2 minutes.
I know it sounds lame and nonsense, but its been annoying me for over a month. I lost my hopes.
It happens exactly the same when i run a modded netsample_prx. *.101 starts sending right away, and for all others IPs I must wait.
I guess it is not my code though.
I just wanna know what the hell is happening! lol

Thanks!
Back to top
View user's profile Send private message
lgnr



Joined: 17 Dec 2009
Posts: 39

PostPosted: Tue Aug 10, 2010 8:48 am    Post subject: Reply with quote

Code:
#include <pspkernel.h>
#include <pspdebug.h>
#include <pspsdk.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pspnet.h>
#include <pspnet_inet.h>
#include <pspnet_apctl.h>
#include <pspnet_resolver.h>
#include <psputility.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/select.h>
#include <errno.h>
#include <fcntl.h>

#define printf pspDebugScreenPrintf
#define sleep sceKernelDelayThread

#define MODULE_NAME "NetSample"

PSP_MODULE_INFO(MODULE_NAME, PSP_MODULE_USER, 1, 1);
PSP_HEAP_SIZE_KB(20480);

static int running = 1;

/* Exit callback */
int exit_callback(int arg1, int arg2, void *common)
{
   running = 0;

   pspSdkInetTerm();

   sceKernelExitGame();

   return 0;
}

/* Callback thread */
int CallbackThread(SceSize args, void *argp)
{
   int cbid;

   cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL);
   sceKernelRegisterExitCallback(cbid);
   sceKernelSleepThreadCB();

   return 0;
}

/* Sets up the callback thread and returns its thread id */
int SetupCallbacks(void)
{
   int thid = 0;

   thid = sceKernelCreateThread("update_thread", CallbackThread,
                 0x11, 0xFA0, PSP_THREAD_ATTR_USER, 0);
   if(thid >= 0)
   {
      sceKernelStartThread(thid, 0, 0);
   }

   return thid;
}

int create_client()
{

   char ip[] = "192.168.0.101";
   int porta = 30666;

   printf("\n\n\n\nOk, ip %s port: %d...\n\n", ip, porta);

   int sock;
      struct sockaddr_in address;

   //Zero mem
   memset(&address, 0, sizeof(address));

   address.sin_family = AF_INET;
      address.sin_port = htons(porta);

   inet_aton(ip, &address.sin_addr);

   sock = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);

   //Non-blocking
   int flags;
   flags = fcntl(sock, F_GETFL, 0);
   fcntl(sock, F_SETFL, flags | O_NONBLOCK);

   int sizeof_msg = 7;   
   char message[7] = "TESTMSG";

   int error;
   
   while(running)
   {      
      error = sendto(sock,message,sizeof_msg,0,(struct sockaddr *)&address,sizeof(address));
      if(error < 0) printf("failure on sendto() - error %d\n", error);
   
      //Evita o erro 10035 (winsock) - mandando mais rapido do que lendo
      sleep(100000);
   }

   close(sock);

   return 0;   
}


/* Connect to an access point */
int connect_to_apctl(int config)
{
   int err;
   int stateLast = -1;

   /* Connect using the first profile */
   err = sceNetApctlConnect(config);
   if (err != 0)
   {
      printf(MODULE_NAME ": sceNetApctlConnect returns %08X\n", err);
      return 0;
   }

   printf(MODULE_NAME ": Connecting...\n");
   while (running)
   {
      int state;
      err = sceNetApctlGetState(&state);
      if (err != 0)
      {
         printf(MODULE_NAME ": sceNetApctlGetState returns $%x\n", err);
         break;
      }
      if (state > stateLast)
      {
         printf("  connection state %d of 4\n", state);
         stateLast = state;
      }
      if (state == 4)
         break;  // connected with static IP

      // wait a little before polling again
      sceKernelDelayThread(50*1000); // 50ms
   }
   printf(MODULE_NAME ": Connected!\n");

   if(err != 0)
   {
      return 0;
   }

   return 1;
}

int thread_client(void)
{
   int thid = 0;
   thid = sceKernelCreateThread("thread_cliente", create_client, 0x18, 0x100000, PSP_THREAD_ATTR_USER, 0);
     if(thid >= 0) {
          sceKernelStartThread(thid, 0, 0);
     }
     return thid;
}

/* Simple thread */
int main(int argc, char **argv)
{
   SceUID thid;

   SetupCallbacks();

   pspDebugScreenInit();

   if(sceUtilityLoadModule(PSP_MODULE_NET_COMMON) != 0) printf("Falhou no primeiro\n");
   
   if(sceUtilityLoadModule(PSP_MODULE_NET_INET) != 0) printf("Falhou no segundo\n");
   
   int err;
   

      if((err = pspSdkInetInit()))
      {
         printf(MODULE_NAME ": Error, could not initialise the network %08X\n", err);
      }

      if(connect_to_apctl(3))
      {
         // connected, get my IPADDR and run test
         char szMyIPAddr[32];
     
         if (sceNetApctlGetInfo(8, szMyIPAddr) != 0)
            strcpy(szMyIPAddr, "unknown IP address");
      }

   //Starts main thread   
   thid = thread_client();

   if(thid < 0)
   {
   sceKernelSleepThread();
   }

   //sleep(1000000);

   //sceKernelSleepThread();

   sceKernelExitDeleteThread(0);

   return 0;
}


This works immediately. BUT, if i change the line to:

Code:
char ip[] = "192.168.0.102";
//Or 103, 104, 216...


I get that crazy delay. I've never seen anything like this. lol
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development All times are GMT + 10 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group