上一篇文章通过客户端通过广播获取了服务器的IP,有了IP之后,就可以通过Socket去连接服务器了
服务器监听端口
/***
* 打开一个socket,开始监听
*/
JNIEXPORT jint JNICALL Java_com_example_jnisocketserver_SocketServer_open
(JNIEnv * env, jobject arg)
{
int server_sockfd;
int client_sockfd;
int len;
struct sockaddr_in my_addr;
struct sockaddr_in remote_addr;
int sin_size;
char buf[1024];
memset(&my_addr,0,sizeof(my_addr));
my_addr.sin_family=AF_INET;
my_addr.sin_addr.s_addr=INADDR_ANY;
my_addr.sin_port=htons(8880);
if((server_sockfd = socket(PF_INET,SOCK_STREAM,0))<0)
{
LOGD("bind socket error: %s",strerror(errno));
return 1;
}
/*将套接字绑定到服务器的网络地址上*/
if (bind(server_sockfd,(struct sockaddr *)&my_addr,sizeof(struct sockaddr))<0)
{
LOGD("bind socket error2: %s",strerror(errno));
return 2;
}
/*监听连接请求--监听队列长度为5*/
listen(server_sockfd,5);
sin_size=sizeof(struct sockaddr_in);
/*等待客户端连接请求到达*/
if((client_sockfd=accept(server_sockfd,(struct sockaddr *)&remote_addr,&sin_size))<0)
{
LOGD("error3");
}
LOGD("accept client %s",inet_ntoa(remote_addr.sin_addr));
len=send(client_sockfd,"Welcome to my server",21,0);//发送欢迎信息
/*接收客户端的数据并将其发送给客户端--recv返回接收到的字节数,send返回发送的字节数*/
while((len=recv(client_sockfd,buf,BUFSIZ,0))>0)
{
buf[len]='\0';
LOGD("%s",buf);
jclass provider = (*env)->FindClass(env,"com/example/jnisocketserver/SocketServer");
if(provider == 0)
LOGD("find class error");
jmethodID getMsg = (*env)->GetMethodID(env,provider,"getMsg","(Ljava/lang/String;)V");
if(getMsg==0)
LOGD("find method error");
LOGD("method id = %d",getMsg);
(*env)->CallVoidMethod(env,arg,getMsg,stoJstring(env,buf));
}
close(client_sockfd);
close(server_sockfd);
return 3;
}
客户端去连接这个socket
/**
* socket连接
*/
JNIEXPORT jint JNICALL Java_com_example_jnisocket_SocketUtil_connet
(JNIEnv *env, jclass arg, jstring ip, jint port)
{
LOGD("ip1=%s",jstringTostring(env,ip));
char* ipstr = jstringTostring(env,ip);
int recbytes;
int len;
char buffer[1024]={0};
struct sockaddr_in s_add,c_add;
int portnum = 8880;
localsocket = socket(AF_INET, SOCK_STREAM, 0);
if(-1 == localsocket)
{
LOGD("error");
}
bzero(&s_add,sizeof(struct sockaddr_in));
LOGD("#######step2");
s_add.sin_family=AF_INET;
s_add.sin_addr.s_addr=inet_addr(ipstr);
s_add.sin_port=htons(port);
LOGD("s_addr = %#x ,port : %#x\r\n",s_add.sin_addr.s_addr,s_add.sin_port);
if(-1 ==connect(localsocket,(struct socketaddr *)(&s_add),sizeof(struct sockaddr)))
{
LOGD("error1 %s",strerror(errno));
}
// LOGD("#######connected to server");
// len = recv(localsocket,buffer,1024,0);
// buffer[len]='\0';
// LOGD("######%s",buffer);
//
// while(1)
// {
// char buff[] = "ss";
// len = send(localsocket,buff,strlen(buff),0);
// len = recv(localsocket,buff,1024,0);
// buff[len]='\0';
// LOGD("#####receive:%s",buff);
// }
// close(localsocket);
return 1;
}
好了,大工告成,基本的通信已经可以实现了,而且由于是用c写的,所以可以实现跨平台操作,但是还有些细节需要优化,比如断线重连,端口被占用之后的处理等待
本文介绍如何在Android中实现局域网内的Socket通信,包括客户端如何利用广播获取服务器IP,然后建立与服务器的连接。

1351

被折叠的 条评论
为什么被折叠?



