Linux服务器与JAVA客户端(android)的socket通信

来源:互联网 发布:pl sql develop 编辑:程序博客网 时间:2024/05/17 02:48

最近因为android客户端要上传信息给Linux服务器的问题一直在Ubuntu上调试,在摸索中发现了许多问题。

1.Linux上创建socket连接的问题

用listenfd = socket(AF_INET, SOCK_STREAM, 0)

   bind(listenfd, (struct sockaddr*) &servaddr, sizeof(servaddr)

   listen(listenfd, 10)

这三个函数就能创建一个socket连接了

2.Linux上建立线程,从而解决多个客户端同时接入的问题。这里我用的是pthread

3.Linux上的接收函数

n = recv(connfd, buff, MAXLINE, 0);

这个函数的意思是,通过connfd这个socket连接,接收最大MAXLINE的数据保存在buff这个指针所指的内存中,返回的n是接收了多少byte的信息。如果n=-1,error。如果n=0,服务器与客户端断开连接。

4.JAVA上传数的问题

本以为这里跟传JAVA服务器一样,传int就用dos.writeInt(int i)方法就行了,结果发现那边接收到的跟发的完全不一样。(接收的话n = recv(connfd, &i, sizeof(int), 0);)

一查发现原来是所谓网络字节和主机字节的问题,还什么高位在前,低位在后的,完全不懂。然后我又调了下JAVA的Integer.size()方法,发现居然是32。我想或许writeInt发的是一个Integer类也说不定。

所以我的总结就是不要用这种方法传数据,直接用dos.write(byte[] b)方法传就行了。简单明了。

而每个数据类型都要得到自己所对应的byte数组。其中string最简单,直接调getbytes方法就行了。

但是因为string的长度不定,所以传之前最好传个int,把多少个字节传过去,服务器也好接收。

各个基本数据类型的转换详见这个博客http://blog.csdn.net/xuanner/article/details/2029022,多谢这位大神让我豁然开朗啊。

特别要提的是int,

private static byte[] InttoByteArray(int n) {        byte[] b = new byte[4];        b[0] = (byte) (n & 0xff);        b[1] = (byte) (n >> 8 & 0xff);        b[2] = (byte) (n >> 16 & 0xff);        b[3] = (byte) (n >> 24 & 0xff);        return b;}
千万别忽略0*ff这个东西,虽然我不懂位操作但事实就是没了这个的话小的int(像1,2,3啊什么的)可以传没问题,一大起来(我那会儿就是560000)马上就出错。这个东西网上有很多版本,一定要先自己试下再用。

差不多也就这么多了,下面把代码贴下吧。linux上编译要加上-pthread,eclipse的话也要在setting里有个地方加pthread,这里我把接收的函数都放到SendandRev.h这个头文件里了。

/** * SendandRev.h *///接收int型数据,返回一个intint receiveInt(int connfd) {int i, n;n = recv(connfd, &i, sizeof(int), 0);if (n == -1 || n == 0) {perror("receive error!");return -1;}return i;}//接收int型数据,返回一个intdouble receiveDouble(int connfd) {double d;int n = recv(connfd, &d, 8, 0);if (n == -1 || n == 0) {perror("receive error!");return -1;}return d;}//接收一个文件,参数是连接ID和保存的路径,以覆盖方式储存,如接收正常返回1,不正常返回-1int receiveFile(int connfd, char* path) {FILE* fp = fopen(path, "wb+");char buff[1024];int n = 1;int size = receiveInt(connfd);printf("size = %d\n", size);while (size > 1024) {n = recv(connfd, buff, 1024, 0);if (n == -1 || n == 0) {perror("接收错误!\n");return -1;}fwrite(buff, 1024, 1, fp);size -= 1024;}n = recv(connfd, buff, size, 0);if (n == -1 || n == 0) {perror("接收错误!\n");return -1;}fwrite(buff, size, 1, fp);printf("receive a file over!\n");fclose(fp);return 1;}//接收一个字符串,参数为连接ID,一个已申请空间的buff数组及其最大容量,完成后返回该数组,若出错返回NULLchar* receiveString(int connfd, char* buff) {int n = 1, size;n = recv(connfd, &size, 4, 0);if (n == -1 || n == 0) {perror("接收错误!\n");return NULL;}n = recv(connfd, buff, size, 0);if (n == -1 || n == 0) {perror("接收错误!\n");return NULL;}buff[n] = '\0';printf("String receive %d bytes!\n", n);return buff;}
/* * Server.c * *  Created on: 2012-7-30 *      Author: sun */#include<stdio.h>#include<stdlib.h>#include<string.h>#include<errno.h>#include<sys/types.h>#include<sys/socket.h>#include<netinet/in.h>#include <pthread.h>#include<SendandRev.h>#define MAXLINE 4096void thread(void* i) {int connfd;connfd = *(int*) i;int choose;char usr_name[50];char usr_password[50];while (1) {choose = receiveInt(connfd);if(choose == -1)break;printf("choose--> %d\n", choose);if (choose ==1) {receiveString(connfd, usr_name);receiveString(connfd, usr_password);printf("usr_name---> %s , usr_password---> %s\n", usr_name,usr_password);continue;}else if (choose == 2) {receiveString(connfd, usr_name);receiveString(connfd, usr_password);printf("usr_name---> %s \nusr_password---> %s\n", usr_name,usr_password);continue;} else if (choose == 3) {receiveString(connfd, usr_name);double gps_longitude = receiveDouble(connfd);double gps_latitude = receiveDouble(connfd);printf("usr_name---> %s \ngps_longitude ---> %f\ngps_latitude --->%f\n", usr_name,gps_longitude, gps_latitude);char path[50];sprintf(path, "/home/sun/%s.jpg", usr_name);receiveFile(connfd, path);continue;} else if (choose == 5) {printf("client exit!\n");close(connfd);break;}}}int main(int argc, char** argv) {pthread_t id;int listenfd, connfd;struct sockaddr_in servaddr;if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {printf("create socket error: %s(errno: %d)\n", strerror(errno), errno);exit(0);}memset(&servaddr, 0, sizeof(servaddr));servaddr.sin_family = AF_INET;servaddr.sin_addr.s_addr = htonl(INADDR_ANY );servaddr.sin_port = htons(6868);if (bind(listenfd, (struct sockaddr*) &servaddr, sizeof(servaddr)) == -1) {printf("bind socket error: %s(errno: %d)\n", strerror(errno), errno);exit(0);}if (listen(listenfd, 10) == -1) {printf("listen socket error: %s(errno: %d)\n", strerror(errno), errno);exit(0);}printf("======waiting for client's request======\n");while (1) {if ((connfd = accept(listenfd, (struct sockaddr*) NULL, NULL )) == -1) {printf("accept socket error: %s(errno: %d)", strerror(errno),errno);continue;}if (pthread_create(&id, NULL, (void *) thread, (void*) &connfd) != 0) {printf("thread create error!");}//n = recv(connfd, buff, MAXLINE, 0);//buff[n] = '\0';//printf("recv msg from client: %s\n", buff);}close(listenfd);}
import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.IOException;import java.net.Socket;import java.net.SocketException;import java.net.UnknownHostException;public class Client {Socket s = null;DataOutputStream dos = null;DataInputStream dis = null;boolean bConnected = false;public static void main(String[] args) {Client c = new Client();c.connect();c.send(1);c.send("hyhx333");c.send("150");c.send(2);c.send("hyhx333");c.send("150");c.send(3);c.send("hyhx333");c.send(123.1);c.send(154.1);c.sendfile("/home/sun/1.jpg");c.send(5);c.close();}private void close() {try {dos.close();s.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}public static byte[] doubleToByte(double d) {byte[] bytes = new byte[8];long l = Double.doubleToLongBits(d);for (int i = 0; i < bytes.length; i++) {bytes[i] = new Long(l).byteValue();l = l >> 8;}return bytes;}public void send(Double d) {try {dos.write(doubleToByte(d));dos.flush();// dos.close();// s.close();} catch (IOException e) {e.printStackTrace();}}public void send(int n) {try {byte[] b = new byte[4];        b[0] = (byte) (n & 0xff);        b[1] = (byte) (n >> 8 & 0xff);        b[2] = (byte) (n >> 16 & 0xff);        b[3] = (byte) (n >> 24 & 0xff);dos.write(b);dos.flush();// dos.close();// s.close();} catch (IOException e) {e.printStackTrace();}}public void connect() {try {s = new Socket("127.0.0.1", 6868);} catch (UnknownHostException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}try {dos = new DataOutputStream(s.getOutputStream());dis = new DataInputStream(s.getInputStream());} catch (IOException e) {e.printStackTrace();}bConnected = true;// new Thread(new Server()).start();}public void sendfile(String path) {byte[] buf = new byte[1024];File file = new File(path);try {FileInputStream fis = new FileInputStream(file);DataOutputStream dos = new DataOutputStream(s.getOutputStream());int size = fis.available();System.out.println("size=" + size);send(size);while (fis.available() > 1024) {fis.read(buf);dos.write(buf);dos.flush();}int remain = -1;while ((remain = fis.read()) != -1) {dos.write(remain);}dos.flush();// dos.close();} catch (Exception e) {e.printStackTrace();}}public void send(String str) {byte[] buf;buf = str.getBytes();int len = buf.length;try {send(len);dos.write(buf);dos.flush();} catch (Exception e) {e.printStackTrace();}}}




原创粉丝点击