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 

receive udp packets?

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



Joined: 28 Oct 2005
Posts: 19

PostPosted: Sun Feb 12, 2006 9:18 am    Post subject: receive udp packets? Reply with quote

hello,

i`m trying to modify psp controller sample,
i`m able to send udp packets and read them on the pc,
but when i try to call sceNetInetRecvfrom psp always freezes,

i would be very grateful if someone can have a look on this
piece of code, i`m sure i`m missung something obvious...
(or maybe there is sample for this somewhere?)

thanks,
wojciech




SOCKET sock = sceNetInetSocket(AF_INET, SOCK_DGRAM, 0);
if (sock & 0x80000000)
{
printf("Could not connect.");
return;
}

sockaddr_in addrTo;

addrTo.sin_family = AF_INET;
addrTo.sin_port = htons(g_serverPort);
addrTo.sin_addr[0] = g_serverAddr[0];
addrTo.sin_addr[1] = g_serverAddr[1];
addrTo.sin_addr[2] = g_serverAddr[2];
addrTo.sin_addr[3] = g_serverAddr[3];


sockaddr_in addrListen;

addrListen.sin_family = AF_INET;
addrListen.sin_port = htons(100); // port 100 - arbitrary
addrListen.sin_addr[0] = 10;
addrListen.sin_addr[1] = 0;
addrListen.sin_addr[2] = 2;
addrListen.sin_addr[3] = 1;


while(done!=1){



char buffer[128];

sockaddr_in addrFrom;
int cbAddrFrom = sizeof(addrFrom);

sceNetInetRecvfrom(sock, (u8*)buffer, sizeof(buffer), 0, &addrFrom, &cbAddrFrom);

unsigned char packet[8];

sceNetInetSendto( sock, packet, sizeof( packet ), 0, &addrTo, sizeof(addrTo) );


}
Back to top
View user's profile Send private message Send e-mail
danzel



Joined: 04 Nov 2005
Posts: 182

PostPosted: Mon Feb 13, 2006 10:28 am    Post subject: Reply with quote

sceNetInetRecvfrom (or recvfrom in standard unix sockets) is a blocking call, it blocks untill it receives a packet.
I guess that this is what is happening.

If you don't want it to block, then investigate using select (http://www.lowtek.com/sockets/select.html) or making it nonblocking and polling it manually.

I also recommend you use the standard unix sockets functionality that is available in the sdk rather than the sceNetInet functions.
Back to top
View user's profile Send private message
w.kosma



Joined: 28 Oct 2005
Posts: 19

PostPosted: Tue Feb 14, 2006 4:28 am    Post subject: Reply with quote

thanks,

i get some connection errors,
is there any sample for dealing with unix sockets?(couldn`t find in the docs)

i`ll be very grateful
btw, i`m on mac os x

wojciech
Back to top
View user's profile Send private message Send e-mail
danzel



Joined: 04 Nov 2005
Posts: 182

PostPosted: Tue Feb 14, 2006 12:31 pm    Post subject: Reply with quote

Fairly good one for tcp:
http://www.cs.rpi.edu/courses/sysprog/sockets/sock.html

Can't really find one for udp, but feel free to post when you get stuck.

Danzel.
Back to top
View user's profile Send private message
sandberg



Joined: 05 Oct 2005
Posts: 90
Location: Denmark

PostPosted: Wed Feb 15, 2006 2:33 am    Post subject: Reply with quote

This my a simple tool I wrote for use with PSPRadio and the WiFi logging stuff. It's intended to run in a Linux shell, but should work on all bsd socket compatible platforms.


Code:

/*
   Simple server application for receiving logdata from PSPRadio.
   Copyright (C) 2006 Jesper Sandberg


   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License
   as published by the Free Software Foundation; either version 2
   of the License, or (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/

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

#define BUFSIZE      1024

void Die(char *message)
{
   perror(message);
   exit(1);
}

int main (int argc, char *argv[])
{
   int            sock;
   struct         sockaddr_in   log_server;
   struct         sockaddr_in   log_client;
   char         buffer[BUFSIZE];
   unsigned int   client_len, server_len;
   int            received = 0;

   fprintf(stdout, "LogTool v0.1 - Written for use with PSPRadio\n\n");


   if (argc != 2)
   {
      fprintf(stderr, "Usage: %s <port>\n", argv[0]);
      exit(1);
   }

   /* Create UDP socket */
   if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
      {
      Die("Failed to create socket..");
      }

   /* Create sockaddr structure */
   memset(&log_server, 0, sizeof(log_server));
   log_server.sin_family      = AF_INET;
   log_server.sin_addr.s_addr   = htonl(INADDR_ANY);
   log_server.sin_port       = htons(atoi(argv[1]));

   /* Bind the socket */
   server_len = sizeof(log_server);
   if (bind(sock, (struct sockaddr *) &log_server, server_len) < 0)
   {
      Die("Failed to bind server socket");
      
   }

   /* Run until cancelled */
   while (1)
   {
      /* Receive datagram from client */
      client_len = sizeof(log_client);
      if ((received = recvfrom(sock, buffer, BUFSIZE, 0, (struct sockaddr *) &log_client, &client_len)) < 0)
      {
         Die("Failed to receive message from client..");
      }
      buffer[received] = 0x00;
      fprintf(stdout, "> %s\n", buffer);
   }

   exit(0);
}

_________________
Br, Sandberg
Back to top
View user's profile Send private message
Sirwhizz



Joined: 08 Jun 2005
Posts: 16
Location: Melbourne, FL

PostPosted: Wed Feb 15, 2006 7:29 am    Post subject: Reply with quote

Well I looked at your code. I have to mention that you need to open two sockets. One for sending and one for receiving. Here is my code.

Code:
int init_UDP_send()
{
      SOCKET sockOut;
      struct sockaddr_in addrOut;
      SceCtrlData pad;
      sceCtrlSetSamplingCycle(0);
      sceCtrlSetSamplingMode(PSP_CTRL_MODE_ANALOG);
      int done = 0;
      int redraw = 1;

      while(!done)
      {

         sceCtrlReadBufferPositive(&pad, 1);
         if(redraw)
         {
            
            pgFillvram(0);
            pgPrint2(5,0,gray, "Choose IP Address");
            IP_Render(IP_s,4,8);
            pgPrint(7,30,midnightblue,"Press X, O when done, HOME to Cancel");
            
            pgScreenFlipV();
            
            redraw = 0;
         }
         
         if(pad.Buttons != 0x02040000)
         {
            if(pad.Buttons & CURSOR_LEFT)
            {
               IP_s--;
               if(IP_s<0) IP_s=16;
            }
            if(pad.Buttons & CURSOR_RIGHT)
            {
                IP_s++;
                if(IP_s>16) IP_s=0;
            }
            if(pad.Buttons & CURSOR_UP)
            {
               IP_Plus(IP_s);
            }
            if(pad.Buttons & CURSOR_DOWN)
            {
               IP_Minus(IP_s);
            }
            if(pad.Buttons & CROSS)
               done = 1;

            if(pad.Buttons & CIRCLE)
               done = 1;

            if(pad.Buttons & EXIT)
            {
               break;
            }
            redraw = 1;
            pgWaitVn(10);
         }
         
         
      }
      sockOut = sceNetInetSocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
       my_printn("socket returned ", sockOut, "\n");
      addrOut.sin_family = AF_INET;
       addrOut.sin_port = htons(IP_p);
      addrOut.sin_addr[0] = (int)(IP_h>>24);
      addrOut.sin_addr[1] = (int)(IP_h>>16)&0xff;
      addrOut.sin_addr[2] = (int)(IP_h>>8)&0xff;
      addrOut.sin_addr[3] = (int)(IP_h)&0xff;

      int buffersize = 0;
      int junk = 1024;


      if (sceNetInetGetsockopt(sockOut, SOL_SOCKET, SO_SNDBUF, (char *)&buffersize,
          &junk) < 0);

      
       int err;
      err = sceNetInetConnect(sockOut, (struct sockaddr*)&addrOut,sizeof(addrOut));

            // any

      return sockOut;
}
int init_UDP_receive()
{
   SOCKET sockListen = 0;
   sockListen = sceNetInetSocket(AF_INET, SOCK_DGRAM, 0);

   u32 timeout = 1000;
   u32 err;
   addrListen.sin_family = AF_INET;
   addrListen.sin_port = htons(100); // port 100 - arbitrary
   addrListen.sin_addr[0] = 0;
   addrListen.sin_addr[1] = 0;
   addrListen.sin_addr[2] = 0;
   addrListen.sin_addr[3] = 0;

   err = sceNetInetSetsockopt(sockListen, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout,  sizeof(timeout));


   err = sceNetInetBind(sockListen, &addrListen, sizeof(addrListen));


   
   return sockListen;
}
void IP_Render(int s, int x, int y) {
    char HostText[] = "000.000.000.000:00000";

    sprintf(HostText, "%3i.%3i.%3i.%3i:%5i", (IP_h>>24), (IP_h>>16)&0xff, (IP_h>>8)&0xff, IP_h&0xff, IP_p);

    if(s<12) { // convert packed to dotted
      int g = s / 3;
      int d = s % 3;
      s=g*4+d;
    } else {
      s+=4;
    }
   pgPrint2(x,y,white, HostText);
    pgPrint2((x+s),(y+1),red, "^");

}
void IP_Minus(int s) {
  long b, g, d = 100;
  if(s<12) {
    g = s / 3;
    s %= 3;
    while(s) { d/=10; s--; }
 
    b = (IP_h>>((3-g)*8))&0xff;
    IP_h &= ~(0xff<<((3-g)*8));
    if (b-d>=0) b-=d;
    else b=0;
    IP_h |= b<<((3-g)*8);
  } else {
    s -= 12;   
    d = 10000;
    while(s) { d/=10; s--; }
 
    if (IP_p-d>=0) IP_p-=d;
    else IP_p = 0;
  }
}

void IP_Plus(int s) {
  long b, g, d = 100;
  if(s<12) {
    g = s / 3;
    s %= 3;
    while(s) { d/=10; s--; }
 
    b = (IP_h>>((3-g)*8))&0xff;
    IP_h &= ~(0xff<<((3-g)*8));
    if (b+d<=0xff) b+=d;
    else b = 0xff;
    IP_h |= b<<((3-g)*8);
  } else {
    s -= 12;   
    d = 10000;
    while(s) { d/=10; s--; }
 
    if (IP_p-d<=0xffff) IP_p+=d;
    else IP_p = 0xffff;
  }
}



This code isn't only mine. I give thanks to PSPPet, PVNC and other great developers out here.

This is how I set up my send and receive for UDP. I made a program that outputs the control buttons and receives JPG images. I still trying to get the PSP to transmit all the time without waiting for the JPG image, but getting it to multithread the two has been a chore for me.

Well anywayz what you are missing is a Bind command on your receive and a Connect command on your send.
Back to top
View user's profile Send private message AIM Address Yahoo Messenger MSN Messenger
sandberg



Joined: 05 Oct 2005
Posts: 90
Location: Denmark

PostPosted: Wed Feb 15, 2006 8:26 am    Post subject: Reply with quote

There is no need to open two sockets ? You can send and receive using the same socket. The addition to my original code above works fine using only one socket.

Quote:

if ((received = recvfrom(sock, buffer, BUFSIZE, 0, (struct sockaddr *) &log_client, &client_len)) < 0)
{
Die("Failed to receive message from client..");
}

if (sendto(sock, buffer, received, 0, (struct sockaddr *) &log_client, sizeof(log_client)) != received)
{
Die("Couldn't send all data..");
}


_________________
Br, Sandberg
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