Problem
I am trying to send a packet from C++ Server to my Android client but the android client is never receiving the packet. I have tried different things on android both the readline and read buffer but these never return anything. Also I am calling the Method to receive packet from the main activity page.
C++ Code
int numBytes; // the number of bytes sent
// Sends the message to the connected host
try
{
string sendMsg = "This is a test \r\n";
if (numBytes = send(socketId, sendMsg.c_str(), sendMsg.size(), 0) == -1)
{
int errorCode = 0;
string errorMsg = "error calling send():\n";
detectErrorSend(&errorCode,errorMsg);
CExceptionEx socketSendException(errorCode,errorMsg);
throw socketSendException;
}
}
catch(CExceptionEx& excp)
{
excp.response();
exit(1);
}
return numBytes;
Android Code
public void RecievePacket()
{
try
{
BufferedReader br = new BufferedReader(new InputStreamReader(mSock.getInputStream()));
String test = br.readLine();
/* BufferedInputStream input = new BufferedInputStream(mSock.getInputStream());
byte[] buffer = new byte[10]; // 10 bytes buffer
int bytesRead = 0;
while( (bytesRead=input.read(buffer)) !=-1 ) { // read up to 10 bytes
String str = new String(buffer,0,bytesRead); // convert bytes to String using default encoding
//System.out.println("Data received: " + str);
}
*/
}
catch (Exception ex)
{
}
}
Note
The commented code block is the the other way I tried to receive the message, also please note that I am able to send packets from Android to C++.
Edit
The send() is sending 0 bytes but i am able to receive packets from android so there must be a connection.
There must be something wrong that's not part of the code you've given us. I wrote my own minimal example running on my own computer using your code, and everything worked as expected. Check if this runs correctly on your computer (run the C++, then the Java). Also check if there's anything I do in my C++ code that you're missing.
socket.cpp: (I'm more of a C programmer, so I just used C++ for the code you provided).
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string>
void connection(int sock)
{
// Pretty much your C++ code verbatim.
std::string sendMsg = "This is a test \r\n";
int amt = send(sock, sendMsg.c_str(), sendMsg.size(), 0);
printf("Send %d bytes.\n", amt);
close(sock);
}
int main(int argc, char *argv[])
{
int sock, csock;
struct sockaddr_in sin;
char *host = "127.0.0.1";
unsigned short port = 1234;
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket");
exit(EXIT_FAILURE);
}
sin.sin_family = AF_INET;
sin.sin_port = htons(port);
if (inet_pton(AF_INET, host, &sin.sin_addr) != 1) {
perror("inet_pton");
exit(EXIT_FAILURE);
}
if (bind(sock, (struct sockaddr*) &sin, sizeof(sin)) != 0) {
perror("bind");
exit(EXIT_FAILURE);
}
if (listen(sock, SOMAXCONN) != 0) {
perror("listen");
exit(EXIT_FAILURE);
}
if ((csock = accept(sock, NULL, NULL)) == -1) {
perror("accept");
exit(EXIT_FAILURE);
}
connection(csock);
close(sock);
return EXIT_SUCCESS;
}
SockTest.java:
import java.net.Socket;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class SockTest {
public static void main(String[] args) {
try {
Socket sock = new Socket("127.0.0.1", 1234);
// Your Java Code Verbatim:
BufferedReader br = new BufferedReader(new InputStreamReader(sock.getInputStream()));
String test = br.readLine();
System.out.println(test);
sock.close();
} catch (Exception ex) {}
}
}
Output for the C++:
$ ./socket
Send 17 bytes.
Output for the Java:
$ java SockTest
This is a test
shouldn't it be
if (numBytes = send(socketId, sendMsg.c_str(), (sendMsg.size() + 1), 0) == -1) ...
Note that +1
Related
I am using esp32 to bring up a tcp server. In order not to access this server by ip, I use mDNS on the esp32 side. I can successfully contact the tcp server from the PC at esp32.local. Now I want to do the same from android application. I wrote a little c ++ code which I run on android.
int sockfd, connfd;
struct sockaddr_in servaddr, cli;
// socket create and varification
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == -1) {
hello ="socket creation failed...";
return env->NewStringUTF(hello.c_str());
}
else
hello="Socket successfully created..\n";
bzero(&servaddr, sizeof(servaddr));
// assign IP, PORT
servaddr.sin_family = AF_INET;
std::string url = "esp32.local";
servaddr.sin_addr.s_addr = inet_addr(url.c_str());
servaddr.sin_port = htons(1234);
struct hostent *result;
result = gethostbyname(url.c_str());
// destAddr.sin_addr.s_addr = ((in_addr*)hosten->h_addr_list[0])->s_addr;
if (!result)
{
hello ="gethostbyname...";
return env->NewStringUTF(hello.c_str());
}
// puts(result->h_name);
memmove(&(servaddr.sin_addr.s_addr), result->h_addr, result->h_length);
// connect the client socket to server socket
if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) != 0) {
hello="connection with the server failed..";
return env->NewStringUTF(hello.c_str());
}
else
printf("connected to the server..\n");
// function for chat
char buff = 0xA;
write(sockfd, &buff, sizeof(buff));
// close the socket
close(sockfd);
When trying to connect from android application, I get an error in function gethostbyname. . What do I need to do to access the .local domain?
std::string url = "esp32.local";
servaddr.sin_addr.s_addr = inet_addr(url.c_str());
inet_addr() does not support parsing hostnames like "sp32.local", only IP addresses. You need to use gethostbyname() or better getaddrinfo() instead.
struct hostent *result;
result = gethostbyname(url.c_str());
...
memmove(&(servaddr.sin_addr.s_addr), result->h_addr, result->h_length);
You are not copying the result of gethostbyname() into the sin_addr.s_addr correctly. Your commented-out code was doing it correctly:
servaddr.sin_addr.s_addr = ((in_addr*)(hosten->h_addr_list[0]))->s_addr;
Which can be simplified to:
servaddr.sin_addr = *(in_addr*)(hosten->h_addr_list[0]);
Or just:
servaddr.sin_addr = *(in_addr*)(hosten->h_addr);
But, getaddrinfo() would be easier to use than populating a sockaddr_in manually. And it supports IPv6, whereas gethostbyname() only supports IPv4:
std::string url = "esp32.local";
int sockfd = -1;
addrinfo hints = {};
addrinfo *result;
hints.ai_family = AF_INET; // AF_UNSPEC
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
// assign IP, PORT
int res = getaddrinfo(url.c_str(), "1234", &hints, &result);
if (res != 0) {
return env->NewStringUTF("getaddrinfo failed...");
}
for(addrinfo *addr = result; addr; addr = addr->ai_next) {
// socket create and varification
sockfd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
if (sockfd == -1) {
continue;
}
// connect the client socket to server socket
if (connect(sockfd, addr->ai_addr, addr->ai_addrlen) != 0) {
close(sockfd);
sockfd = -1;
continue;
}
break;
}
if (sockfd == -1) {
freeaddrinfo(result);
return env->NewStringUTF("socket creation/connect failed...");
}
freeaddrinfo(result);
printf("Connected to the server..\n");
// function for chat
char buff = 0xA;
write(sockfd, &buff, sizeof(buff));
// close the socket
close(sockfd);
I want to recieve text data from remote android bluetooth. I had written simple winApi server, but it doesnt respond to remote android sending. The connection was fine and did responds( paired) using control panel manager with my bluetooth. When sending and recieving over control panel manager was working fine. But This time, I want to test using some c++ winapi. Here's my code so far. It was adapted from somewhere codeproject site :)
#include <stdio.h>
#include <stdlib.h>
#include <sstream>
#include <string>
#include <tchar.h>
#include <WinSock2.h>
#include <ws2bth.h>
#include <BluetoothAPIs.h>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
WORD wVersionRequested = 0x202;
WSADATA m_data;
if (0 == WSAStartup(wVersionRequested, &m_data))
{
SOCKET s = socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
const DWORD lastError = GetLastError();
if (s == INVALID_SOCKET)
{
ostringstream stream;
stream << lastError;
string data= stream.str();
printf("Failed to get bluetooth socket! %s\n", data.c_str());
return 1;
}
WSAPROTOCOL_INFO protocolInfo;
int protocolInfoSize = sizeof(protocolInfo);
if (0 != getsockopt(s, SOL_SOCKET, SO_PROTOCOL_INFO,
(char*)&protocolInfo, &protocolInfoSize))
{
return 1;
}
SOCKADDR_BTH address;
address.addressFamily = AF_BTH;
address.btAddr = 0;
address.serviceClassId = GUID_NULL;
address.port = BT_PORT_ANY;
sockaddr *pAddr = (sockaddr*)&address;
if (0 != bind(s, pAddr, sizeof(SOCKADDR_BTH)))
{
ostringstream stream;
stream << GetLastError();
string data= stream.str();
printf("%s\n", data.c_str() );
}
else
{
printf("\nBinding Successful....\n");
int length = sizeof(SOCKADDR_BTH) ;
getsockname(s,(sockaddr*)&address,&length);
wprintf (L"Local Bluetooth device is %04x%08x \nServer channel = %d\n",
GET_NAP(address.btAddr), GET_SAP(address.btAddr), address.port);
}
int size = sizeof(SOCKADDR_BTH);
if (0 != getsockname(s, pAddr, &size))
{
ostringstream stream;
stream << GetLastError();
string data= stream.str();
printf("%s\n", data.c_str());
}
if (0 != listen(s, 10))
{
ostringstream stream;
stream << GetLastError();
string data= stream.str();
printf("%s\n", data.c_str());
}
WSAQUERYSET service;
memset(&service, 0, sizeof(service));
service.dwSize = sizeof(service);
// service.lpszServiceInstanceName = reinterpret_cast<LPWSTR>(_T("Accelerometer Data..."));
//service.lpszServiceInstanceName = ;
// service.lpszComment = reinterpret_cast<LPWSTR>(_T("Pushing data to PC"));
GUID serviceID = OBEXFileTransferServiceClass_UUID;
service.lpServiceClassId = &serviceID;
service.dwNumberOfCsAddrs = 1;
service.dwNameSpace = NS_BTH;
CSADDR_INFO csAddr;
memset(&csAddr, 0, sizeof(csAddr));
csAddr.LocalAddr.iSockaddrLength = sizeof(SOCKADDR_BTH);
csAddr.LocalAddr.lpSockaddr = pAddr;
csAddr.iSocketType = SOCK_STREAM;
csAddr.iProtocol = BTHPROTO_RFCOMM;
service.lpcsaBuffer = &csAddr;
if (0 != WSASetService(&service, RNRSERVICE_REGISTER, 0))
{
printf("Service registration failed....");
ostringstream stream;
stream << GetLastError();
string data= stream.str();
printf("%d\n", data.c_str());
}
else
{
printf("\nService registration Successful....\n");
}
HANDLE hRadio ;
BLUETOOTH_FIND_RADIO_PARAMS btfrp = { sizeof(BLUETOOTH_FIND_RADIO_PARAMS) };
HBLUETOOTH_RADIO_FIND hFind = BluetoothFindFirstRadio(&btfrp, &hRadio);
if ((hFind != NULL)&& (hRadio !=NULL))
{
if (BluetoothEnableDiscovery(hRadio,TRUE)){
printf("BluetoothEnableDiscovery() is working!\n");
}
if (BluetoothEnableIncomingConnections(hRadio,TRUE)){
printf("BluetoothEnableIncomingConnections() is working!\n");
}
if (BluetoothIsConnectable(hRadio)){
printf("BluetoothIsConnectable() is working!\n");
}
}
printf("\nBefore accept.........");
SOCKADDR_BTH sab2;
int ilen = sizeof(sab2);
SOCKET s2 = accept (s,(sockaddr*)&sab2, &ilen);
if (s2 == INVALID_SOCKET)
{
wprintf (L"Socket bind, error %d\n", WSAGetLastError ());
}
wprintf (L"\nConnection came from %04x%08x to channel %d\n",
GET_NAP(sab2.btAddr), GET_SAP(sab2.btAddr), sab2.port);
wprintf (L"\nAfter Accept\n");
char buffer[1024] = {0};
memset(buffer, 0, sizeof(buffer));
int r = recv(s2,(char*)buffer, sizeof(buffer), 0);
printf("%s\n",buffer);
closesocket(s2);
if (0 != WSASetService(&service, RNRSERVICE_DELETE, 0))
{
ostringstream stream;
stream << GetLastError();
string data= stream.str();
printf("%s\n", data.c_str());
}
closesocket(s);
WSACleanup();
return 0;
}
}
I use microsoft BT device btw..
Just to be sure: you said you're on WinXP... OK, but WinXP SP3 with Microsoft BT stack and appropriate dongle? or another XP version and another BT stack (like Widcomm or BlueSoleil...)?
In the later case, BT Socket API won't work...
Otherwise, not much to say about the code, except a missing BluetoothFindRadioClose...
I'm trying to share data between kernel and user space. The ultimate goal is to port it to Android, so I'm using unix domain sockets. (I don't know if this is the best option).
I have a kernel module acting as socket client and a c program acting as socket server. And vice-versa, a kernel module acting as socket server and a c program acting as socket client.
Programs are very simple. Servers just send a string to clients and they print it.
I run server_user.c and then I try to insert client_module.ko using insmod. I get the following error:
Kernel panic - not syncing: stack - protector: Kernel stack is corrupted in: ffffffffa0005157
drm-kms-helper: panic occurred, switching back to text console
What's wrong?
Module Server
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/socket.h>
#include <linux/net.h>
#include <linux/un.h>
#include <net/sock.h>
#define SOCK_PATH "/tmp/usocket"
#define LISTEN 10
struct socket *sock = NULL;
struct socket *newsock = NULL;
static int __init server_module_init( void ) {
int retval;
char* string = "hello_world";
struct sockaddr_un addr;
struct msghdr msg;
struct iovec iov;
mm_segment_t oldfs;
// create
retval = sock_create(AF_UNIX, SOCK_STREAM, 0, &sock);
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
strcpy(addr.sun_path, SOCK_PATH);
// bind
retval = sock->ops->bind(sock,(struct sockaddr *)&addr, sizeof(addr));
// listen
retval = sock->ops->listen(sock, LISTEN);
//accept
retval = sock->ops->accept(sock, newsock, 0);
//sendmsg
memset(&msg, 0, sizeof(msg));
memset(&iov, 0, sizeof(iov));
msg.msg_name = 0;
msg.msg_namelen = 0;
msg.msg_iov = &iov;
msg.msg_iov->iov_base = string;
msg.msg_iov->iov_len = strlen(string)+1;
msg.msg_iovlen = 1;
msg.msg_control = NULL;
msg.msg_controllen = 0;
msg.msg_flags = 0;
oldfs = get_fs();
set_fs(KERNEL_DS);
retval = sock_sendmsg(newsock, &msg, strlen(string)+1);
set_fs(oldfs);
return 0;
}
static void __exit server_module_exit( void ) {
printk(KERN_INFO "Exit usocket.");
}
module_init( server_module_init );
module_exit( server_module_exit );
MODULE_LICENSE("GPL");
Module Client
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/un.h>
#include <linux/net.h>
#include <net/sock.h>
#include <linux/socket.h>
#define SOCK_PATH "/tmp/usocket"
#define MAX 100
struct socket *sock = NULL;
static int __init client_module_init( void ) {
int retval;
char str[MAX];
struct sockaddr_un addr;
struct msghdr msg;
struct iovec iov;
mm_segment_t oldfs;
printk(KERN_INFO "Start client module.\n");
// create
retval = sock_create(AF_UNIX, SOCK_STREAM, 0, &sock);
// connect
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
strcpy(addr.sun_path, SOCK_PATH);
retval = sock->ops->connect(sock, (struct sockaddr *)&addr, sizeof(addr), 0);
// recvmsg
memset(&msg, 0, sizeof(msg));
memset(&iov, 0, sizeof(iov));
msg.msg_name = 0;
msg.msg_namelen = 0;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_iov->iov_base= str;
msg.msg_iov->iov_len= strlen(str)+1;
msg.msg_control = NULL;
msg.msg_controllen = 0;
msg.msg_flags = 0;
oldfs = get_fs();
set_fs(KERNEL_DS);
retval = sock_recvmsg(sock, &msg, strlen(str)+1, 0);
set_fs(oldfs);
// print str
printk(KERN_INFO "client module: %s.\n",str);
// release socket
sock_release(sock);
return 0;
}
static void __exit client_module_exit( void )
{
printk(KERN_INFO "Exit client module.\n");
}
module_init( client_module_init );
module_exit( client_module_exit );
MODULE_LICENSE("GPL");
User Server
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#define SOCK_PATH "/tmp/usocket"
int send_msg_to_client(int socketfd, char* data) {
struct msghdr msg;
struct iovec iov;
int s;
memset(&msg, 0, sizeof(msg));
memset(&iov, 0, sizeof(iov));
msg.msg_name = NULL;
msg.msg_namelen = 0;
iov.iov_base = data;
iov.iov_len = strlen(data)+1;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_control = NULL;
msg.msg_controllen = 0;
msg.msg_flags = 0;
s = sendmsg(socketfd, &msg, 0);
printf("after send - iov_base: %s, length: %d\n", (char *) msg.msg_iov->iov_base, (int) strlen(msg.msg_iov->iov_base));
if(s < 0){
perror("sendmsg");
return 0;
}
return s;
}
int main(int argc, char* argv[])
{
if (argc != 2) {
printf("Usage: $ %s <string>\n",argv[0]);
return 0;
}
int s, s2, len, slen;
socklen_t t;
struct sockaddr_un local, remote;
char* data = argv[1];
printf("print data: %s\n",data);
if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
perror("socket");
exit(1);
}
memset(&local, 0, sizeof(local));
local.sun_family = AF_UNIX;
strcpy(local.sun_path, SOCK_PATH);
unlink(local.sun_path);
len = strlen(local.sun_path) + sizeof(local.sun_family);
if (bind(s, (struct sockaddr *)&local, len) == -1) {
perror("bind");
exit(1);
}
if (listen(s, 5) == -1) {
perror("listen");
exit(1);
}
printf("Waiting for a connection...\n");
t = sizeof(remote);
if ((s2 = accept(s, (struct sockaddr *)&remote, &t)) == -1) {
perror("accept");
exit(1);
}
printf("Connected.\n");
slen = send_msg_to_client(s2, data);
if(slen < 0)
perror("send");
close(s2);
return 0;
}
User Client
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#define SOCK_PATH "/tmp/usocket"
#define MAX 100
int recv_msg_from_server(int socketfd, char data[MAX]) {
struct msghdr msg;
struct iovec iov;
int s;
memset(&msg, 0, sizeof(msg));
memset(&iov, 0, sizeof(iov));
msg.msg_name = NULL;
msg.msg_namelen = 0;
iov.iov_base = data;
iov.iov_len = MAX;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_control = NULL;
msg.msg_controllen = 0;
msg.msg_flags = 0;
s = recvmsg(socketfd, &msg, 0);
printf("after recv - iov_base: %s, length: %d\n", (char *) msg.msg_iov->iov_base, (int) strlen(msg.msg_iov->iov_base));
if(s < 0){
perror("recvmsg");
}
return s;
}
int main(void)
{
int s, len, slen;
struct sockaddr_un remote;
char data[MAX];
if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
perror("socket");
exit(1);
}
printf("Trying to connect...\n");
memset(&remote, 0, sizeof(remote));
remote.sun_family = AF_UNIX;
strcpy(remote.sun_path, SOCK_PATH);
len = strlen(remote.sun_path) + sizeof(remote.sun_family);
if (connect(s, (struct sockaddr *)&remote, len) == -1) {
perror("connect");
exit(1);
}
printf("Connected.\n");
slen = recv_msg_from_server(s, data);
if (slen < 0) {
perror("recvmsg");
}
//printf("print data received > %s\n", data);
close(s);
return 0;
}
I have just faced a similar issue (with UNIX datagrams though), and I believe there is a bug in the unix_mkname() function which is part of the kernel: this function makes sure the sun_path field of the given sockaddr_un structure is always null terminated by adding a NUL character after the end of that field. Since this is the last field, it will corrupt the area (stack or heap) where that structure has been allocated.
The best solution is to patch that function in the kernel source code, so that it only sets to NUL the last character of the sun_path field. Meanwhile, you can make your code work by decreasing by 1 byte the size you give for the sockaddr_un structure:
Module Server
// bind
retval = sock->ops->bind(sock,(struct sockaddr *)&addr, sizeof(addr) - 1);
Module Client
retval = sock->ops->connect(sock, (struct sockaddr *)&addr, sizeof(addr) - 1, 0);
As I am using UNIX datagrams, I cannot really tell if it fixes the issue for bind() and connect(), but a least, it fixes it for sock_sendmsg().
#shu-suzuki: thanks for the leads.
After 5 years I came back here...
I again stucked with this problem and found that I did the same thing 5 years ago.
The cause is as in Tey's answer and the solution is OK (sutbract 1 from the length) but here's another solution.
What you can do is to use struct sockaddr_storage as struct sockaddr_un. As far as I read the kernel code this is what they use to handle bind system call from user space.
sockeaddr_storage is larger than sockaddr_un so kernel code can write beyond the sizeof(sockaddr_un).
The code should be like
struct sockaddr_storage addrStorage;
struct sockaddr_un* addr;
memset(&addrStorage, 0, sizeof(addrStorage));
addr = (struct sockaddr_un*)&addrStorage;
addr->sun_family = AF_UNIX;
strcpy(addr->sun_path, "/my/sock/name");
kernel_bind(listenSock, (struct sockaddr*)addr, sizeof(*addr));
This looks working for me.
I am new to android and iam trying to read a file from SD card using NDK and sending that read bytes to SDK and iam writing it to the SD card using SDK (for checking).. I could sucefully make a call from NDK - SDK with the bytes and i could write it to the SD card using SDK.. But i coulnt open the file written to the sd card..
I am pasting my code
Native C file
#include<stdio.h>
#include<string.h>
#include <jni.h>
#include <stdlib.h>
#include <android/log.h>
#include "com_example_fileupload_NativeLib.h"
#define LOG_TAG "testjni"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
JavaVM *m_vm;
jobject obj;
jclass gFilePermInfoClass;
jmethodID gFilePermInfoClsConstructor;
jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
JNIEnv* env;
LOGI("JNI INIT");
return JNI_VERSION_1_6;
}
JNIEXPORT jint JNICALL Java_com_example_fileupload_NativeLib_loop
(JNIEnv *env, jobject obj)
{
LOGI("JNI work !");
jbyteArray data;
jbyteArray data_rem;
jclass clazz = (*env)->FindClass(env,"com/example/fileupload/NativeLib");
if (clazz == 0) {
LOGI("FindClass error");
return 2;
}
gFilePermInfoClass = (*env)->NewGlobalRef(env, clazz);
LOGI("JNI before jmethodID");
jmethodID javamethod = (*env)->GetMethodID(env,gFilePermInfoClass, "callFromCPP", "([B)V");
gFilePermInfoClsConstructor = (*env)->NewGlobalRef(env, javamethod);
if (javamethod == 0) {
LOGI("GetMethodID error");
return 3;
}
LOGI("JNI before calling java ");
LOGI(" before File ");
FILE *fd = NULL;
char buff[1*1024*1024];
char *h;
unsigned int nread = 0;
unsigned int nread_remaining = 0;
int count=0;
memset(buff, '\0', sizeof(buff));
fd = fopen("/sdcard/20MB.zip","r+");
fseek ( fd, 0 , SEEK_END );
int fileSize = ftell(fd);
LOGI("****SUDARSHAN C SIZE %d",fileSize);
if(NULL == fd) // Check for error
{
LOGI("\n File opening failed\n");
return 1;
}
nread = (1*1024*1024); // Hard code the number of elements to 50
if(nread_remaining = fileSize%nread)
{
count = fileSize/nread;
LOGI("***** IN IF rem %d",nread_remaining);
}
else{
count = fileSize/nread;
LOGI("***** IN ELSE COUNT %d",count);
}
data = (*env)->NewByteArray(env, nread);
data_rem = (*env)->NewByteArray(env, nread_remaining);
if(data == NULL){
LOGI("No memory could be allocated for buffer");
return -1;
}
LOGI("Before While in C ");
int count_test=0;
int i;
for(i=count;i>0;i--) //while(count_test) //while( fread(buff, 1, nread, fd) )
{
fread(buff, 1, nread, fd);
LOGI("INSIUDE WHILE SUDARSHAN **** %d",i);
(*env)->SetByteArrayRegion(env, data, 0, nread, buff);
(*env)->CallVoidMethod(env, obj, gFilePermInfoClsConstructor, data);
}
if(nread_remaining){
char buffer[nread_remaining];
fread(buffer, 1, nread_remaining, fd);
(*env)->SetByteArrayRegion(env, data_rem, 0, nread_remaining, buffer);
(*env)->CallVoidMethod(env, obj, gFilePermInfoClsConstructor, data_rem);
}
if(feof(fd))
{
printf("\n Seems like end of file was reached\n");
}
else if(ferror(fd))
{
printf("\n Some errors on this stream occurred\n");
}
// Reset the buffer with NULLs
memset(buff, '\0', sizeof(buff));
return (10+11);
}
NativeLib.java
package com.example.fileupload;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import android.os.Environment;
public class NativeLib {
public int count=0;
File someFile = null;
FileOutputStream fos = null;
File sdDir = new File(Environment.getExternalStorageDirectory().getPath());
public NativeLib() throws FileNotFoundException{
someFile = new File(sdDir.getPath() +"/22MB.zip");
fos = new FileOutputStream(someFile);
//fos.flush();fos.close();
}
static {
System.loadLibrary("com_example_fileupload_NativeLib");
}
/**
* Adds two integers, returning their sum
*/
public native int loop();
/**
* Returns Hello World string
* #throws IOException
*/
//public native String hello();
public void callFromCPP(byte[] buff)
{
count=count+buff.length;
try {
//count=count+buff.length;
System.out.println("************ Sudarshan Inside callfromcpp try "+count+" "+buff.length);
fos.write(buff);
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.println("************ Sudarshan Inside callfromcpp catch "+e.toString());
e.printStackTrace();
}
// count=count+buff.length;
//System.out.println("************ Sudarshan Inside callfromcpp 1 "+buff.toString()+" "+count);
}
Iam calling the native fn. loop() from my MainActivity.java and the java fn. call from native is callFromCPP(byte[] buff) and here only iam writing the byte's to SD card (named 22MB.zip) returned from native..
PLZ help
Reagards,
Deepak
I found the mistake i had done,.. there is a limit for "fread" function to read bytes.. I had given 1MB (nread value in my c fle) which is too large.. So i changed the value to 100 and it worked
Regards,
Deepak
I'm trying to produce a simple server that will allow me test the Androids security features. I need to develop an application that will open a socket.
I've produced something similar in C, but I am having no look with java. Here's the application in C
// simpleserver3.c
#define MY_PORT 9999
#define MAXBUF 99
void indata(int clientfd, struct sockaddr_in client_addr)
{
char buffer[12];
printf("%s:%d connected\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
recv(clientfd, buffer, MAXBUF, 0); //this is will overflow the buffer
printf("%X \n", &buffer);
}
int main(int Count, char *Strings[])
{
struct sockaddr_in self, client_addr;
int sockfd,clientfd;
/*---Create streaming socket---*/
if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) //socketfd = handle for socket
{
perror("Socket");
exit(errno);
}
/*---Initialize address/port structure---*/
bzero(&self, sizeof(self));
self.sin_family = AF_INET;
self.sin_port = htons(MY_PORT);
self.sin_addr.s_addr = INADDR_ANY;
/*---Bind the structure to the socket handle ---*/
if ( bind(sockfd, (struct sockaddr*)&self, sizeof(self)) != 0 )
{
perror("socket--bind");
exit(errno);
}
/*---Make it a "listening socket"---*/
if ( listen(sockfd, 20) != 0 )
{
perror("socket--listen");
exit(errno);
}
//set socklen_t to length of client address
socklen_t addrlen=sizeof(client_addr);
/*---accept a connection (creating a data pipe)---*/
clientfd = accept(sockfd, (struct sockaddr*)&client_addr, &addrlen); //create handle for communicating
indata(clientfd, client_addr);
close(clientfd);
close(sockfd);
return;
}
Any sugguestion would be great, Aneel
It's been a while since I used C, so I can't comment on your C code, but you should probably take a look at the Android documentation for the Socket class:
http://developer.android.com/reference/java/net/Socket.html
Check out this example: http://thinkandroid.wordpress.com/2010/03/27/incorporating-socket-programming-into-your-applications/