receive udp packets?

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

Post Reply
w.kosma
Posts: 19
Joined: Fri Oct 28, 2005 11:33 pm

receive udp packets?

Post by w.kosma »

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) );


}
danzel
Posts: 182
Joined: Fri Nov 04, 2005 11:03 pm

Post by danzel »

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.
w.kosma
Posts: 19
Joined: Fri Oct 28, 2005 11:33 pm

Post by w.kosma »

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
danzel
Posts: 182
Joined: Fri Nov 04, 2005 11:03 pm

Post by danzel »

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.
sandberg
Posts: 90
Joined: Wed Oct 05, 2005 1:25 am
Location: Denmark

Post by sandberg »

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: Select all

/*
	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&#40;char *message&#41;
&#123;
	perror&#40;message&#41;;
	exit&#40;1&#41;;
&#125;

int main &#40;int argc, char *argv&#91;&#93;&#41;
&#123;
	int				sock;
	struct			sockaddr_in	log_server;
	struct			sockaddr_in	log_client;
	char			buffer&#91;BUFSIZE&#93;;
	unsigned int	client_len, server_len;
	int				received = 0;

	fprintf&#40;stdout, "LogTool v0.1 - Written for use with PSPRadio\n\n"&#41;;


	if &#40;argc != 2&#41;
	&#123;
		fprintf&#40;stderr, "Usage&#58; %s <port>\n", argv&#91;0&#93;&#41;;
		exit&#40;1&#41;;
	&#125;

	/* Create UDP socket */
	if &#40;&#40;sock = socket&#40;PF_INET, SOCK_DGRAM, IPPROTO_UDP&#41;&#41; < 0&#41;
		&#123;
		Die&#40;"Failed to create socket.."&#41;;
		&#125;

	/* Create sockaddr structure */
	memset&#40;&log_server, 0, sizeof&#40;log_server&#41;&#41;;
	log_server.sin_family		= AF_INET;
	log_server.sin_addr.s_addr	= htonl&#40;INADDR_ANY&#41;;
	log_server.sin_port 		= htons&#40;atoi&#40;argv&#91;1&#93;&#41;&#41;;

	/* Bind the socket */
	server_len = sizeof&#40;log_server&#41;;
	if &#40;bind&#40;sock, &#40;struct sockaddr *&#41; &log_server, server_len&#41; < 0&#41;
	&#123;
		Die&#40;"Failed to bind server socket"&#41;;
		
	&#125;

	/* Run until cancelled */
	while &#40;1&#41;
	&#123;
		/* Receive datagram from client */
		client_len = sizeof&#40;log_client&#41;;
		if &#40;&#40;received = recvfrom&#40;sock, buffer, BUFSIZE, 0, &#40;struct sockaddr *&#41; &log_client, &client_len&#41;&#41; < 0&#41;
		&#123;
			Die&#40;"Failed to receive message from client.."&#41;;
		&#125;
		buffer&#91;received&#93; = 0x00;
		fprintf&#40;stdout, "> %s\n", buffer&#41;;
	&#125;

	exit&#40;0&#41;;
&#125;
Br, Sandberg
Sirwhizz
Posts: 16
Joined: Wed Jun 08, 2005 4:12 am
Location: Melbourne, FL

Post by Sirwhizz »

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: Select all

int init_UDP_send&#40;&#41;
&#123;
		SOCKET sockOut;
		struct sockaddr_in addrOut;
		SceCtrlData pad;
		sceCtrlSetSamplingCycle&#40;0&#41;;
		sceCtrlSetSamplingMode&#40;PSP_CTRL_MODE_ANALOG&#41;;
		int done = 0;
		int redraw = 1;

		while&#40;!done&#41;
		&#123;

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

				if&#40;pad.Buttons & CIRCLE&#41;
					done = 1;

				if&#40;pad.Buttons & EXIT&#41;
				&#123;
					break;
				&#125;
				redraw = 1;
				pgWaitVn&#40;10&#41;;
			&#125;
			
			
		&#125;
		sockOut = sceNetInetSocket&#40;AF_INET, SOCK_DGRAM, IPPROTO_UDP&#41;;
	    my_printn&#40;"socket returned ", sockOut, "\n"&#41;;
		addrOut.sin_family = AF_INET;
	    addrOut.sin_port = htons&#40;IP_p&#41;;
		addrOut.sin_addr&#91;0&#93; = &#40;int&#41;&#40;IP_h>>24&#41;;
		addrOut.sin_addr&#91;1&#93; = &#40;int&#41;&#40;IP_h>>16&#41;&0xff;
		addrOut.sin_addr&#91;2&#93; = &#40;int&#41;&#40;IP_h>>8&#41;&0xff;
		addrOut.sin_addr&#91;3&#93; = &#40;int&#41;&#40;IP_h&#41;&0xff;

		int buffersize = 0;
		int junk = 1024;


		if &#40;sceNetInetGetsockopt&#40;sockOut, SOL_SOCKET, SO_SNDBUF, &#40;char *&#41;&buffersize,
 			&junk&#41; < 0&#41;;

		
	    int err;
		err = sceNetInetConnect&#40;sockOut, &#40;struct sockaddr*&#41;&addrOut,sizeof&#40;addrOut&#41;&#41;;

            // any

		return sockOut;
&#125;
int init_UDP_receive&#40;&#41;
&#123;
	SOCKET sockListen = 0;
	sockListen = sceNetInetSocket&#40;AF_INET, SOCK_DGRAM, 0&#41;;

	u32 timeout = 1000;
	u32 err;
	addrListen.sin_family = AF_INET;
	addrListen.sin_port = htons&#40;100&#41;; // port 100 - arbitrary
	addrListen.sin_addr&#91;0&#93; = 0;
	addrListen.sin_addr&#91;1&#93; = 0;
	addrListen.sin_addr&#91;2&#93; = 0;
	addrListen.sin_addr&#91;3&#93; = 0;

	err = sceNetInetSetsockopt&#40;sockListen, SOL_SOCKET, SO_RCVTIMEO, &#40;char *&#41;&timeout,  sizeof&#40;timeout&#41;&#41;;


	err = sceNetInetBind&#40;sockListen, &addrListen, sizeof&#40;addrListen&#41;&#41;;


	
	return sockListen;
&#125;
void IP_Render&#40;int s, int x, int y&#41; &#123;
    char HostText&#91;&#93; = "000.000.000.000&#58;00000";

    sprintf&#40;HostText, "%3i.%3i.%3i.%3i&#58;%5i", &#40;IP_h>>24&#41;, &#40;IP_h>>16&#41;&0xff, &#40;IP_h>>8&#41;&0xff, IP_h&0xff, IP_p&#41;;

    if&#40;s<12&#41; &#123; // convert packed to dotted
      int g = s / 3;
      int d = s % 3;
      s=g*4+d;
    &#125; else &#123;
      s+=4;
    &#125;
	pgPrint2&#40;x,y,white, HostText&#41;;
    pgPrint2&#40;&#40;x+s&#41;,&#40;y+1&#41;,red, "^"&#41;;

&#125;
void IP_Minus&#40;int s&#41; &#123;
  long b, g, d = 100;
  if&#40;s<12&#41; &#123;
    g = s / 3;
    s %= 3;
    while&#40;s&#41; &#123; d/=10; s--; &#125;
  
    b = &#40;IP_h>>&#40;&#40;3-g&#41;*8&#41;&#41;&0xff;
    IP_h &= ~&#40;0xff<<&#40;&#40;3-g&#41;*8&#41;&#41;;
    if &#40;b-d>=0&#41; b-=d;
    else b=0;
    IP_h |= b<<&#40;&#40;3-g&#41;*8&#41;;
  &#125; else &#123;
    s -= 12;    
    d = 10000;
    while&#40;s&#41; &#123; d/=10; s--; &#125;
  
    if &#40;IP_p-d>=0&#41; IP_p-=d;
    else IP_p = 0;
  &#125;
&#125;

void IP_Plus&#40;int s&#41; &#123;
  long b, g, d = 100;
  if&#40;s<12&#41; &#123;
    g = s / 3;
    s %= 3;
    while&#40;s&#41; &#123; d/=10; s--; &#125;
  
    b = &#40;IP_h>>&#40;&#40;3-g&#41;*8&#41;&#41;&0xff;
    IP_h &= ~&#40;0xff<<&#40;&#40;3-g&#41;*8&#41;&#41;;
    if &#40;b+d<=0xff&#41; b+=d;
    else b = 0xff;
    IP_h |= b<<&#40;&#40;3-g&#41;*8&#41;;
  &#125; else &#123;
    s -= 12;    
    d = 10000;
    while&#40;s&#41; &#123; d/=10; s--; &#125;
  
    if &#40;IP_p-d<=0xffff&#41; IP_p+=d;
    else IP_p = 0xffff;
  &#125;
&#125;

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.
sandberg
Posts: 90
Joined: Wed Oct 05, 2005 1:25 am
Location: Denmark

Post by sandberg »

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.
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
Post Reply