Socket通信:Linux服务器与多个Android客户端
16lz
2021-01-23
Socket通信:Linux服务器与多个Android客户端
1. Linux Server:
#include //head files of Linux#include #include //for fork and read #include //for socket #include //for socket #include // for bzero #include#include #include using namespace std;struct data { int server_fd; unsigned int sin_size;};void *acceptClient(void *param) { data *data1 = (data *) param; int client_fd; int sock = data1->server_fd; unsigned int sin_size = data1->sin_size; sockaddr_in remoteAddr; const int MAXSIZE = 1024; if ((client_fd = accept(sock, (sockaddr *) (&remoteAddr), &sin_size)) == -1) { cerr << "accept error!" << endl; } cout << " 已和用户建立链接 " << static_cast<char *>(inet_ntoa(remoteAddr.sin_addr)) << endl; // ---------------- 逻辑部分 -------------------// int count = -1; while (count<5) { count++; if (1) { //----接受消息 cout<<"\n 等待接受消息..."<int rval; char buf[MAXSIZE]; if ((rval = read(client_fd, buf, MAXSIZE)) < 0) { cout << "Reading stream error!\n"; continue; } cout << "用户发送的信息为:" << buf << endl; //-----发送消息 const char *msg = "67.8元"; if (send(client_fd, const_cast<char *>(msg), strlen(msg), 0) == -1) cerr << "send error!" << endl; } } } close(client_fd);// exit(0);}void server(){ // 参数设置 const unsigned short SERVERPORT = 53553; const int BACKLOG = 10; //10 个最大的连接数 const int MAXSIZE = 1024; int sock, client_fd; sockaddr_in myAddr; sockaddr_in remoteAddr; sock = socket(AF_INET, SOCK_STREAM, 0); //create socket if( sock == -1) { cerr<<"socket create fail!"<exit(1); } cout<<"sock :"<// bind myAddr.sin_family = AF_INET; myAddr.sin_port = htons(SERVERPORT); myAddr.sin_addr.s_addr = INADDR_ANY; bzero( &(myAddr.sin_zero), 8); if(bind(sock, (sockaddr*)(&myAddr), sizeof(sockaddr)) ==-1 ) { cerr<<"bind error!"<exit(1); } // 服务器ip和端口 cout << " server ip: " << inet_ntoa(myAddr.sin_addr) << endl; cout << " server port: " << SERVERPORT <//myAddr.sin_port //listen if(listen(sock, BACKLOG) == -1) { cerr<<"listen error"<exit(1); } // 创建多个线程连接用户端 pthread_t tids[BACKLOG]; int threadID = 0; while(threadID<10) { unsigned int sin_size = sizeof(sockaddr_in); data threadParam; threadParam.server_fd = sock; threadParam.sin_size = sin_size; int ret = pthread_create(&tids[threadID],NULL,acceptClient,(void *)&threadParam); threadID++; if (ret != 0) { cout << "pthread_create error: error_code=" << ret << endl; }}
2. Android 客户端
import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.support.v7.app.AppCompatActivity;import android.support.v7.widget.Toolbar;import android.view.View;import android.widget.EditText;import android.widget.TextView;import android.widget.Toast;import java.io.BufferedReader;import java.io.DataInputStream;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStream;import java.net.Socket;public class MainActivity extends AppCompatActivity { private TextView editText_1; private EditText editText_ip,editText_data; private OutputStream outputStream = null; private Socket socket = null; private String ip; private String data; private boolean socketStatus = false; StringBuffer stringBuffer = new StringBuffer(); private String textToShow = "待支付金额:"; public Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { switch (msg.what){ case 1: textToShow+="\n"; textToShow+=msg.obj.toString(); editText_1.setText(textToShow); break; case 2: editText_1.setText(msg.obj.toString()); stringBuffer.setLength(0); break; } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); editText_ip = (EditText) findViewById(R.id.et_ip); editText_data = (EditText) findViewById(R.id.et_data); editText_1 = (TextView) findViewById(R.id.text1); } public void connect(View view){ ip = editText_ip.getText().toString(); if(ip == null){ Toast.makeText(MainActivity.this,"please input Server IP",Toast.LENGTH_SHORT).show(); } Thread thread = new Thread(){ @Override public void run() { super.run(); if (!socketStatus) { try { // ip 和端口要和服务器一致 socket = new Socket(ip,53553); if(socket == null){ }else { socketStatus = true; } outputStream = socket.getOutputStream(); } catch (IOException e) { Toast.makeText(MainActivity.this,"socket connect failed",Toast.LENGTH_SHORT).show(); e.printStackTrace(); } } } }; thread.start(); } public void send(View view){ // 发送数据 data = editText_data.getText().toString(); if(data == null){ Toast.makeText(MainActivity.this,"please input Sending Data",Toast.LENGTH_SHORT).show(); }else { //在后面加上 '\0' ,是为了在服务端方便我们去解析; data = data + '\0'; } Thread thread = new Thread(){ @Override public void run() { super.run(); if(socketStatus){ try { outputStream.write(data.getBytes()); } catch (IOException e) { e.printStackTrace(); } } //接受返回数据 int len; byte[] bytes = new byte[20]; InputStream inputStream; StringBuffer stringBuffer = new StringBuffer(); try{ inputStream = socket.getInputStream(); while ((len = inputStream.read(bytes)) != -1) { for(int i=0; ichar)bytes[i]); } Message message = handler.obtainMessage(); message.what = 1; message.obj = stringBuffer; handler.sendMessage(message); break; } } catch (Exception e){ } } }; thread.start(); } /*当客户端界面返回时,关闭相应的socket资源*/ @Override public void onBackPressed() { super.onBackPressed(); /*关闭相应的资源*/ try { outputStream.close(); socket.close(); } catch (IOException e) { e.printStackTrace(); } }}
权限:
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.INTERNET" />
- 服务器端ip说明:ip = 0.0.0.0 可以本机和本机的端口间任意通信,在局域网中,要使用192.168.xxx.xxx的ip,保证客户端和服务器端口ip一致
最后,完整demo,以及Linux的客户端,Andoird的服务器端的下载链接:
http://download.csdn.net/download/burning_keyboard/10229385
更多相关文章
- 服务器向Android写一个对象
- Android与(Servlet)服务器交互
- Android与PHP服务器交互
- Android腾讯微薄客户端开发十三:提及篇(与我有关的微博)
- android web服务器
- Android腾讯微薄客户端开发十二:博主的偶像
- android 上传文件到服务器