basic4android Server Socket - android

I'm trying to do a two ways communication between a PC running .NET Client-Server and an Android device, (the code is made with Basic4Android).
Sending from Android to PC works fine, the problem occours when i try to send from the PC to Android.
I'm trying to use the ServerSocket but when the PC tries to connect to the Android the device, time-out is reached and an exception is raised. The code i'm using is the following:
PC .NET
Dim sock As New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
sock.Connect(remoteip, 8565)
Dim buffer() As Byte = UTF8.GetBytes(string)
sock.Send(buffer)
sock.Close()
and the Android code:
Sub Process_Globals
'These global variables will be declared once when the application starts.
'These variables can be accessed from all modules.
Dim ss As ServerSocket
Dim IS1 As InputStream
Dim timerListener As Timer
End Sub
Sub Activity_Create(FirstTime As Boolean)
timerListener.Initialize(timerListener, 1)
ss.Initialize(8565, "ss")
ss.Listen
End Sub
Sub ss_NewConnection (Successful As Boolean, NewSocket As Socket)
If Successful Then
IS1 = NewSocket.InputStream
timerListener.Enabled = True
Else
ToastMessageShow("Error.", True)
End If
End Sub
Sub timerListener_Tick
Dim cv As ByteConverter
If IS1.BytesAvailable > 0 Then
Dim buffer() As Byte
IS1.ReadBytes(buffer, 0, IS1.BytesAvailable)
Dim result As String = cv.StringFromBytes(buffer, "UTF8")
ToastMessageShow(result, True)
timerListener.Enabled = False
End If
End Sub
What can be the issue?
Thank you in advance!!

You should use AsyncStreams to read the data.
In your PC read a byte from the stream after you write the message. This will cause the thread to wait for the byte to be available instead of closing the socket before the device read the message.

In Sub timerListener_Tick(), control the timer action:
timerListener.Enabled = False
...
timerListener.Enabled = True
Timer will receive the messages periodly.

Closing the PC socket straight after sending will cause you a send error because it's closing when you are in fact still sending, better to use a global variable to hold the socket instance, but if you want to send synchronous (wait for the transfer to commit) use the example from MSDN.
Synchronous Client Socket Example
I wouldn't recommend it though, personally, I would prefer to use async transfers, like one of the above post recommends.
See->Asynchronous Client Socket Example

Related

Casting audio with local server socket

I'm trying to fix an existing project which is casting video and audio to the web.
I need to create local socket:
socketId = "my.application.media." + suffix + "-" + new
Random().nextInt();
localServerSocket = new LocalServerSocket(socketId);
receiver = new LocalSocket();
receiver.connect(new LocalSocketAddress(socketId));
receiver.setReceiveBufferSize(SOCKET_BUFFER_SIZE);
receiver.setSendBufferSize(SOCKET_BUFFER_SIZE);
sender = localServerSocket.accept();
sender.setReceiveBufferSize(SOCKET_BUFFER_SIZE);
sender.setSendBufferSize(SOCKET_BUFFER_SIZE);
and creating media recorder:
mMediaRecorder = new MediaRecorder();
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.RAW_AMR);
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mMediaRecorder.setAudioEncodingBitRate((int) 7.95 * 1024);
mMediaRecorder.setAudioSamplingRate(8000);
mMediaRecorder.setAudioChannels(1);
mMediaRecorder.setOutputFile(sender.getFileDescriptor());
mMediaRecorder.prepare();
But I'm getting java.lang.IllegalStateException after calling start on mMediaRecorder. What am I missing? When I'm not using sender.getFileDescriptor() everything is working correctly so probably that's the problem. I know that there are many libraries which are providing this functionality but I prefer to fix this one. Casting the only video is working correctly and the only problem is with the audio. Thanks a lot for help.
Order of executed methods:
added logs to check the order of methods and thread:
creating sockets: Socket opening thread
creating receiver: Socket opening thread
creating sender: Socket opening thread
setting audio source: Socket opening thread
setting properties: Socket opening thread
creating file descriptor: Socket opening thread
preparing media recorder: Socket opening thread
starting media recorder: Socket opening thread
I found that I'm also receiving errors:
2019-02-13 18:15:49.701 6176-13833/? E/StagefrightRecorder: Output file descriptor is invalid
2019-02-13 18:15:49.701 7851-9780/my.application E/MediaRecorder: start failed: -38
As stated here this error java.lang.IllegalStateException occurring when
a method has been invoked at an illegal or inappropriate time.
So with that in mind and with this article in mind of how to use sockets, You should put your socket related staff inside AsyncTask (separated thread) and use try catch.
AsyncTask Documentation , and Socket Documentation if you want to expand your knowledge.
As it seems you are trying to use getFileDescriptor before (or after if it close) sender have the data to pull it out.
Try extracting the data at earlier location in the code to a variable and than use this variable instead.
Another possibility could be; MediaRecorder documentation says
You must specify a file descriptor that represents an actual file
so be sure that the type that sender.getFileDescriptor() return is the right type that mMediaRecorder.setAudioChannels can get.

Receiving socket information from netfilter NF_INET_PRE_ROUTING hook function in linux kernel

I wrote a netfilter hook function for incoming packets in linux kernel. Is there a way to get the receiving socket information from the hook function. The code is
register() {
hk.hook = hookfunction;
hk.hooknum = NF_INET_PRE_ROUTING;
hk.pf = PF_INET;
hk.priority = NF_IP_PRI_LAST;
}
static unsigned int hookfunction (void *priv,struct sk_buff,const struct nf_hook_state *state) {
if (skb->sk) {
printk("%d", skb->sk->sk_mark);
}
}
Lets assume I have a udp socket open at port 15000 and a udp packet arrives at port 15000. In the above written hook function how can I access the struct sock of the udp socket opened at port 15000. With the above code, the control doesnot pass the if(skb->sk) condition as if skb->sk is null. Can you please suggest me a way to get the struct sock of the socket or should I have to put the hook in some other position like NF_INET_LOCAL_IN,. I am also confused about the difference between NF_INET_XX_XX and NF_IP_XX_XX.
The kernel uses __inet_lookup_skb() internally to get sk from skb, which calls skb_steal_sock() first to check if skb->sk is NULL, if that is the case, it then calls __inet_lookup() to lookup sk.
However you might need to tweak the kernel a little bit because __inet_lookup_skb symbol is not exported and can't be called directly.
Some references from kernel source:
1 2 3
Regarding NF_INET_XX if you are talking about NF_IP_PRE_ROUTING and NF_INET_PRE_ROUTING I believe NF_IP_PRE_ROUTING is obsolete in recent kernel, as far as I know 4.4 has replaced it with NF_INET_PRE_ROUTING.
Hope that helps.

Using polling in jeromq

I am learning to use zeromq polling in android . I am polling on a req socket and a sub socket in the android program(client). So that this client can receive both reply messages from the server and also published messages.
My polling is not working. Both the req socket and the publish socket does not get polled in. If i don't use polling both the sockets receive the message.
I tried searching online but could not find anything relevant.
The client code is this :
public void run()
{
ZMQ.Context context = ZMQ.context(1);
ZMQ.Socket reqsocket = context.socket(ZMQ.REQ);
ZMQ.Socket subsocket =context.socket(ZMQ.SUB);
reqsocket.connect("tcp://10.186.3.174:8081");
subsocket.connect("tcp://10.186.3.174:8083");
subsocket.subscribe("".getBytes());
byte[] receivedmessage;
Poller poller=context.poller();
poller.register(reqsocket,Poller.POLLIN);
poller.register(subsocket,Poller.POLLIN);
reqsocket.send(msg.getBytes(),0);
while(!Thread.currentThread().isInterrupted())
{
if(poller.pollin(0))
{
receivedmessage=s.recv(0);
}
if(poller.pollin(0))
{
receivedmessage=subsocket.recv(0);
}
}
s.close();
context.term();
}
Am i missing out something or doing something wrong?
It looks like there are 3 problems with this.
The main one is you need to call poller.poll() as the first thing inside the while loop. This is why you are not getting any messages.
The next issue is that you're checking the same index for both sockets: I expect the second if statement needs to be
if(poller.pollin(1))
Lastly, the req socket requires a send before every receive, so the call to send needs to be inside the while loop, and before the poller.poll() you just added above :)

Receiving hexadecimal values from socket instead of strings on SocketServer

I opened a socket between an Android app and a python server. The combination is that the Server listens, and android connects to the Server.
Here is the server code. The problematic part takes place in the definition of handle :
import SocketServer
from time import sleep
import sys
HOST = '192.168.56.1'
PORT = 2000
class SingleTCPHandler(SocketServer.StreamRequestHandler):
def handle(self):
try:
while(1):
sleep(0.03)
data = self.rfile.readline().strip()
print data
except KeyboardInterrupt:
sys.exit(0)
class SimpleServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
allow_reuse_address = True
def __init__(self, server_address, RequestHandlerClass):
SocketServer.TCPServer.__init__(self, server_address, RequestHandlerClass)
server = SimpleServer((HOST, PORT), SingleTCPHandler)
try:
server.serve_forever()
except KeyboardInterrupt:
sys.exit(0)
The connection is established normally, and the Android app sends the following data to the socket:
'0:0'
But the data is received on the Server as:
'\x000\x00:\x000\x00'
The variable that receives the data is:
data = self.rfile.readline().strip()
and printing gives the regular format:
In [2]: print data
0:0
I didn't manage to step into the print function with pdb to see what it does.
I'm looking for a way to convert the '\x000\x00:\x000\x00' to '0:0'.
Please advise on a way to convert the variable. You are welcome to comment/criticize the whole implementation. This is my first project in dealing with sockets so i don't know the pitfalls.
Update
This was the original Android code:
String podaci = "0:0";
public void Socketic() throws IOException {
Socket mojSocket = new Socket(urlServer, port);
DataOutputStream izlazdata = new DataOutputStream(
mojSocket.getOutputStream());
while (podaci != "end") {
try {
Thread.sleep(60);
} catch (InterruptedException e) {
e.printStackTrace();
}
izlazdata.writeChars(podaci);
izlazdata.flush();
}
izlazdata.close();
mojSocket.close();
};
And the problem was, as you suspected in:
izlazdata.writeChars(podaci);
writeChars uses the method writeChar. The API documentation for writeChar states:
Writes a char to the underlying output stream as a 2-byte value, high byte first...
The two bytes represent the 16bits which UTF-16 uses for encoding.
When we changed it to everything started working:
izlazdata.writeBytes(podaci);
Update
Based on the answers given, here is how the unwanted string is to be interpreted in terms of characters.
This solves my concrete problem, however, if someone would give a more generic solution to what happend here so that a larger lesson can be learned.
If not, i will accept Esailijas answer in a few days.
You need to show the code happening Android but it strongly seems like it's sending data in UTF-16BE. You should specify the encoding on the Android end. The characters are not hexadecimal literally, but because the NUL character is unprintable, python shows \x00 instead.
Another option is to decode it:
self.rfile.readline().decode("utf_16_be").strip()
note that the result of this is an unicode string.

Errno 97 with Android NDK socket programming

I've searched all over google and can't find a solution to this problem:
I'm trying to do some basic socket programming (client/server apps) on my Android device and I'm not having any luck starting the Server app. In my native code, I call bind(...) and I see from the log that it returns -1. When I check errno, the value is 97 (EAFNOSUPPORT), which indicates "Address family not supported by protocol." When I checked the values for sin_family, it was AF_INET, which is IPv4. Is this not supported by the Android NDK? If not, what else could be the cause of this error?
Socket is initialized as:
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP));
listenAddr is a sockaddr_in struct that's initialized with:
sin_family = AF_INET;
sin_port = htons(9099);
sin_addr.s_addr = INADDR_NONE;
Call to bind:
bindResult = bind(sock, (sockaddr *)listenAddr, sizeof(listenAddr))
Bind result returns -1. Subsequent call to errno returns 97.
Use INADDR_ANY (or a specific interface's address) rather than INADDR_NONE.
INADDR_NONE is an unsigned constant with the same bit pattern as the signed value -1, returned as an indication of error from certain calls.

Categories

Resources