一、搭建阿里云步骤
1.1 大概流程
2.2 我这里申请一个免费版本的。
2.3 找到这个服务器
2.4 点击控制台
2.5 就可以看到服务器的大概参数
2.6 最好改一下密码
2.7 然后点击“远程连接”
2.8 就可以进入命令控制界面
2.9 也可以在自己的电脑使用ssh进行登录
2.10 可以ping通上面的外网IP地址,说明云服务器就可以了。
2.11 最后增加规则,开放对应端口,不然无法进行socket通讯,我们后面的例子使用9999端口。
三、让两个手机(或移动设备)通过 Socket 实现通信,即使它们都在内网或用流量。
3.1 relay_server.c 运行在云服务器上面
// relay_server.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <netinet/in.h>
#include <errno.h>
#define PORT 9999
#define MAX_CLIENTS 2
int client_socks[MAX_CLIENTS];
int client_count = 0;
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
void* client_handler(void* arg) {
int sock = *(int*)arg;
char buffer[1024];
while (1) {
//int len = recv(sock, buffer, sizeof(buffer) - 1, 0);
//if (len <= 0) {
// break;
// }
printf("rec sock=%d......\n",sock);
ssize_t len = recv(sock, buffer, sizeof(buffer), 0);
if (len <= 0) {
if (errno == EWOULDBLOCK || errno == EAGAIN) {
printf("recv timeout\n");
continue;}
else {
perror("recv error");
break;
}
}
buffer[len] = '\0';
printf("收到客户端(sock=%d)消息: %s ;len=%d\n", sock,buffer,len);
pthread_mutex_lock(&lock);
for (int i = 0; i < client_count; ++i) {
if (client_socks[i] != sock) {
send(client_socks[i], buffer, strlen(buffer), 0);
}
}
pthread_mutex_unlock(&lock);
}
printf("close sock=%d\n",sock);
close(sock);
pthread_mutex_lock(&lock);
for (int i = 0; i < client_count; ++i) {
if (client_socks[i] == sock) {
for (int j = i; j < client_count - 1; ++j) {
client_socks[j] = client_socks[j + 1];
}
client_count--;
break;
}
}
pthread_mutex_unlock(&lock);
return NULL;
}
int main() {
int server_sock = socket(AF_INET, SOCK_STREAM, 0);
int opt = 1;
setsockopt(server_sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); // allow reuse of local address
struct sockaddr_in server_addr = {0};
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(PORT);
server_addr.sin_addr.s_addr = INADDR_ANY;
//bind(server_sock, (struct sockaddr*)&server_addr, sizeof(server_addr));
// listen(server_sock, MAX_CLIENTS);
if (bind(server_sock, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
perror("bind failed");
exit(1);
}else
printf("bind ok\n");
if (listen(server_sock, MAX_CLIENTS) < 0) {
perror("listen 失败");
exit(1);
}
printf("The server is working..,listen port is %d...\n", PORT);
while (1) {
printf("waiting new client to connect...\n");
int client_sock = accept(server_sock, NULL, NULL);
printf("there is a new client connect sock id = %d \n",client_sock);
struct timeval timeout;
timeout.tv_sec = 10;
timeout.tv_usec = 0;
setsockopt(client_sock, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
pthread_mutex_lock(&lock);
if (client_count < MAX_CLIENTS) {
client_socks[client_count++] = client_sock;
pthread_t tid;
pthread_create(&tid, NULL, client_handler, &client_sock);
pthread_detach(tid);
} else {
printf("No client sock available\n");
send(client_sock, "连接人数已满\n", 14, 0);
close(client_sock);
}
pthread_mutex_unlock(&lock);
}
close(server_sock);
return 0;
}
3.2 一台家里的ubuntu电脑和一台公司的ubuntu电脑分别都运行clinet.c
// client.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define SERVER_IP "39.xxx.x8.x"
#define PORT 9999
void* recv_thread(void* arg) {
int sock = *(int*)arg;
char buffer[1024];
while (1) {
int len = recv(sock, buffer, sizeof(buffer) - 1, 0);
if (len <= 0) break;
buffer[len] = '\0';
printf("Recv:%s\n", buffer);
}
return NULL;
}
int main() {
int sock = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in server_addr = {0};
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(PORT);
inet_pton(AF_INET, SERVER_IP, &server_addr.sin_addr);
printf("client app start!\n");
if (connect(sock, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
perror("连接失败");
return 1;
}else
printf("connected\n");
pthread_t tid;
pthread_create(&tid, NULL, recv_thread, &sock);
char input[1024]="home pc\n";
while (1) {
printf("Please input:\n");
//fgets(input, sizeof(input), stdin);
// if (strncmp(input, "exit", 4) == 0) break;
printf("ready to send data %s\n",input);
//send(sock, input, strlen(input), 0);
ssize_t sent = send(sock, input, strlen(input), 0);
if (sent <= 0) {
printf("Failed to send data\n");
return -1; // Error or disconnected
}
sleep(1);
}
close(sock);
return 0;
}
3.3运行效果如下,可以看到我家里面的电脑可以通过阿里云服务器和我公司电脑的ubuntu进行socket通讯,算是最简单的服务器。
四、参考文章