我正在努力在Android设备(客户端)和PC(服务器)之间实现TCP套接字,该代码由c ++(Android NDK)实现。
每件事情都很好,当我跑到服务器端时输出“服务器启动”它等待连接到客户端。另一方面,当我为客户端运行时,它工作直到连接到服务器,我发现此错误“套接字连接到服务器错误”
任何人都可以告诉我想要的是问题吗?
我想将矩阵16 * 16从服务器传输到客户端并将客户端形成服务器......
服务器端:
MyServerThread::MyServerThread()
{
startServer();
}
void MyServerThread::run()
{
//std::cout<<"hi"<<std::endl;
for(int i=0;i<16;i++)
matrix[i]=(float)i;
memcpy(buf,matrix,4*16);
sendMSG();
}
//TCP socket
/* now create the server socket
make it an IPV4 socket (PF_INET) and stream socket (TCP)
and 0 to select default protocol type */
if ( (server_skt = socket(AF_INET, SOCK_STREAM, 0)) == -1 ){
std::cerr<<"socket creation failed"<<std::endl;
exit(1);
}
//Initail, bind to port
/* now fill in values of the server sockaddr_in struct
s_addr and sin_port are in Network Byte Order (Big Endian)
Since Intel CPUs use Host Byte Order (Little Endian), conversion
is necessary (e.g. htons(), and htonl() */
server_addr.sin_family = AF_INET;//IPv4
server_addr.sin_port = htons(PORT);
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
memset(server_addr.sin_zero, 0, 8);
//binding
/* now bind server port
associate socket (server) with IP address:port (server_addr) */
if ( bind(server_skt, (struct sockaddr*)&server_addr, sizeof(struct sockaddr)) == -1 ){
std::cerr<<"socket bind failed"<<std::endl;
exit(1);
}
int queueSize=1;
//Start listening, wait for connection from client with a pending queue of size
if ( listen(server_skt, queueSize) == -1 ){
std::cerr<<"socket listen failed"<<std::endl;
exit(1);
}
//Wait for connect!
bool gotClient=false;
while(!gotClient){
sin_size = sizeof(struct sockaddr_in);
socklen_t temp=sin_size;
std::cout<<"server starts"<<std::endl;
if ( (client_skt = accept(server_skt, (struct sockaddr*)&clients_addr, &temp)) == -1 ){
std::cerr<<"socket error"<<std::endl;}
else
{
gotClient=true;
std::cout<<"Got client"<<std::endl;
}
}
void MyServerThread::sendMSG()
{
if ( (numbytes = send(client_skt, buf, strlen(buf),0)) == -1){
std::cerr<<"server, normal send error"<<std::endl;
exit(1);
}
}
void MyServerThread::recvMSG()
{
if ( (numbytes = recv(client_skt, buf, bufferSize,0)) == -1 ){
std::cerr<<"server, normal recv error"<<std::endl;
exit(1);
}
}
客户端:
Client::Client()
{
}
void Client::startClient()
{
/* now fill in sockaddr_in for remote address */
serv_addr.sin_family = AF_INET;
/* save the server IP (input from Java */
serv_addr.sin_addr.s_addr = inet_addr(serverIP);
/* set port */
serv_addr.sin_port = htons(PORT);
memset(serv_addr.sin_zero, 0, 8);
/* create local stream socket */
client_skt = socket(PF_INET, SOCK_STREAM, 0);
if (client_skt < 0) {
__android_log_print(ANDROID_LOG_ERROR,"jni client","socket creation error");
exit(-1);
}
/* bind local socket to any port number */
local_addr.sin_family = AF_INET;
local_addr.sin_addr.s_addr = htonl(INADDR_ANY);
//local_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
local_addr.sin_port = htons(PORT);
memset(local_addr.sin_zero, 0, 8);
rc = bind(client_skt, (struct sockaddr *) &local_addr, sizeof(local_addr));
if (rc < 0)
{
__android_log_print(ANDROID_LOG_ERROR,"jni client","socket bind error");
exit(1);
}
__android_log_print(ANDROID_LOG_INFO,"jni client","client start finished");
}
void Client::connectServer()
{
__android_log_print(ANDROID_LOG_INFO,"jni client","connect to server starts");
/* connect to server */
rc = connect(client_skt, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
if (rc < 0)
{
__android_log_print(ANDROID_LOG_ERROR,"jni client","socket connect to server error");
exit(1);
}
__android_log_print(ANDROID_LOG_ERROR,"jni client","server connected");
}
void Client::sendMSG()
{
if ( (numbytes = send(client_skt, "hello!", strlen("hello!"),0) )== -1 ){
__android_log_print(ANDROID_LOG_ERROR,"jni client","send error");
//exit(1);
}
}
void Client::recvMSG()
{
if ( (numbytes = recv(client_skt, buf, bufferSize,0) ) == -1 ){
__android_log_print(ANDROID_LOG_ERROR,"jni client","recv error");
//exit(1);
}
else
{
memcpy (matrix, buf, numbytes);
for(int i=0;i<4;i++)
__android_log_print(ANDROID_LOG_INFO,"matrix","%f, %f, %f, %f",matrix[i*4],matrix[i*4+1],matrix[i*4+2],matrix[i*4+3]);
}
}
此致
答案 0 :(得分:0)
如果客户端和服务器位于同一台计算机上,则connect()
可能会因EADDRINUSE(本地地址已被使用)而失败,因为您将客户端和服务器绑定到相同的端口号:
local_addr.sin_port = htons(PORT);
编辑客户端代码,将客户端绑定到端口0(这意味着内核将为您选择一个未使用的临时端口),然后重试。
即使这不是您遇到的确切问题,也应始终记录库函数返回的错误。 connect()
失败后,请记录strerror(errno)
。