编辑:在其他任何事情之前,我知道TCP和UDP是什么,以及差异,但是如何解释我能够从客户端从服务器接收,但不能发送,如下所示......?< / p>
我在C中创建了一个服务器应用程序,在Java中创建了一个客户端应用程序,我将其部署到Android。 我有一个奇怪的问题,我无法克服。
当我的手机IP发生变化时(例如,当切换到移动网络时,从Wifi,或反之亦然),C中的应用程序不再能够接收数据,只是为了发送,即使手机发送它,也没有任何错误
重新连接到同一网络时不会发生这种情况。
我尝试了很多东西,并以C:
结束了这一点void *receive_thread(){
pthread_detach(pthread_self());
struct sockaddr_in dest; /* socket info about the machine connecting to us */
struct sockaddr_in serv; /* socket info about our server */
int mysocket; /* socket used to listen for incoming connections */
socklen_t socksize = sizeof(struct sockaddr_in);
memset(&serv, 0, sizeof(serv)); /* zero the struct before filling the fields */
serv.sin_family = AF_INET; /* set the type of connection to TCP/IP */
serv.sin_addr.s_addr = htonl(INADDR_ANY); /* set our address to any interface */
serv.sin_port = htons(PORTNUMRCV); /* set the server port number */
mysocket = socket(AF_INET, SOCK_STREAM, 0);
//fcntl(mysocket, F_SETFD, O_NONBLOCK);
/* bind serv information to mysocket */
bind(mysocket, (struct sockaddr *)&serv, sizeof(struct sockaddr));
/* start listening, allowing a queue of up to 1 pending connection */
listen(mysocket, 1);
int consocket = accept(mysocket, (struct sockaddr *)&dest, &socksize);
while(consocket){
//socklen_t fromlen;
//fromlen = sizeof inet_ntoa(dest.sin_addr);
char receivemsg[128];
int rlen = recv(consocket, &receivemsg, 128, 0); //receive data
int err = errno;
//printf("recv error: %d\n", err);
printf("Received string: %s from %s \n", receivemsg, inet_ntoa(dest.sin_addr));
if(rlen > 0){
receivemsg[rlen] = '\0';
if(comparestr(KEY, receivemsg) == 1){
printf("Local client\n");
incrementor++;
} else if(comparestr(KEY, receivemsg) == 2){
printf("Remote client\n");
incrementor--;
} else {
printf("Wrong key!\n");
}
} else {
printf("Care!!!! Receiving: %d \n", rlen);
}
close(consocket);
consocket = accept(mysocket, (struct sockaddr *)&dest, &socksize);
}
printf("Receive thread ended!\n");
receive_thread_up = 0;
}
void *send_thread(){
pthread_detach(pthread_self());
struct sockaddr_in dest; /* socket info about the machine connecting to us */
struct sockaddr_in serv; /* socket info about our server */
int mysocket; /* socket used to listen for incoming connections */
socklen_t socksize = sizeof(struct sockaddr_in);
memset(&serv, 0, sizeof(serv)); /* zero the struct before filling the fields */
serv.sin_family = AF_INET; /* set the type of connection to TCP/IP */
serv.sin_addr.s_addr = htonl(INADDR_ANY); /* set our address to any interface */
serv.sin_port = htons(PORTNUMSND); /* set the server port number */
mysocket = socket(AF_INET, SOCK_STREAM, 0);
/* bind serv information to mysocket */
bind(mysocket, (struct sockaddr *)&serv, sizeof(struct sockaddr));
/* start listening, allowing a queue of up to 1 pending connection */
listen(mysocket, 1);
int consocket = accept(mysocket, (struct sockaddr *)&dest, &socksize);
while(consocket){
//printf("Incoming connection from %s - sending string\n", inet_ntoa(dest.sin_addr));
int slen = send(consocket, KEY, 3*sizeof(KEY), 0); //send data
if(slen>0)printf("Sent string: %s to %s \n", KEY, inet_ntoa(dest.sin_addr));
else {
printf("Care!!! Sending: %d \n", slen);
}
close(consocket);
consocket = accept(mysocket, (struct sockaddr *)&dest, &socksize);
}
printf("Send thread ended!\n");
send_thread_up = 0;
}
这就是Java:
public static int sendString(String str) throws IOException{
System.out.println("Sending string: " + str);
out.println(str);
return 0;
}
public static String receiveString(){
String s = " ";
try {
s = in.readLine();
} catch (SocketException e) {
System.out.println("Socket Exception: " + e);
} catch (IOException e) {
System.out.println("IOException on receive: " + e);
}
System.out.println("Received string: " + s);
return s;
}
public static String reverseString(String str){
String newStr = " ";
newStr = new StringBuilder(str).reverse().toString();
return newStr;
}
我的猜测是recv卡住,因此我尝试添加
fcntl(mysocket, F_SETFD, O_NONBLOCK);
,在不工作之后,我评论了它。 也许使用UDP套接字?我可能会遇到诸如消息未到达或未完整等问题。 我们也欢迎改进我的代码的建议!
这是C:
中的输出Thread: No connection, waiting...
Sent string: I4mP4ssw0rd7 to 192.168.1.2
Received string: I4mP4ssw0rd7
from 192.168.1.2
Local client
Sent string: I4mP4ssw0rd7 to 192.168.1.2
Thread: Local connection!
Received string: I4mP4ssw0rd7
from 192.168.1.2
Local client
Sent string: I4mP4ssw0rd7 to 192.168.1.2
Sent string: I4mP4ssw0rd7 to 87.edited
Sent string: I4mP4ssw0rd7 to 87.edited
Sent string: I4mP4ssw0rd7 to 87.edited
Sent string: I4mP4ssw0rd7 to 87.edited
Sent string: I4mP4ssw0rd7 to 87.edited
以下是Java的输出:
03-18 22:52:45.831 13899-13899/willymatica.alarmapp1 I/System.out﹕ Connected!
03-18 22:52:49.375 13899-13920/willymatica.alarmapp1 I/System.out﹕ Connected locally!
03-18 22:52:49.585 13899-13920/willymatica.alarmapp1 I/System.out﹕ Received string: I4mP4ssw0rd7
03-18 22:52:54.900 13899-13920/willymatica.alarmapp1 I/System.out﹕ Sending string: I4mP4ssw0rd7
03-18 22:52:54.910 13899-13920/willymatica.alarmapp1 I/System.out﹕ Connected locally!
03-18 22:52:54.970 13899-13920/willymatica.alarmapp1 I/System.out﹕ Received string: I4mP4ssw0rd7
03-18 22:53:00.265 13899-13920/willymatica.alarmapp1 I/System.out﹕ Sending string: I4mP4ssw0rd7
03-18 22:53:00.285 13899-13920/willymatica.alarmapp1 I/System.out﹕ Connected locally!
03-18 22:53:00.315 13899-13920/willymatica.alarmapp1 I/System.out﹕ Received string: I4mP4ssw0rd7
03-18 22:53:05.631 13899-13920/willymatica.alarmapp1 I/System.out﹕ Sending string: I4mP4ssw0rd7
03-18 22:53:05.631 13899-13920/willymatica.alarmapp1 I/System.out﹕ Connected remotely!
03-18 22:53:05.851 13899-13920/willymatica.alarmapp1 I/System.out﹕ Received string: I4mP4ssw0rd7
03-18 22:53:11.266 13899-13920/willymatica.alarmapp1 I/System.out﹕ Sending string: 7dr0wss4Pm4I
03-18 22:53:11.286 13899-13920/willymatica.alarmapp1 I/System.out﹕ Connected remotely!
03-18 22:53:11.516 13899-13920/willymatica.alarmapp1 I/System.out﹕ Received string: I4mP4ssw0rd7
03-18 22:53:16.912 13899-13920/willymatica.alarmapp1 I/System.out﹕ Sending string: 7dr0wss4Pm4I
03-18 22:53:16.932 13899-13920/willymatica.alarmapp1 I/System.out﹕ Connected remotely!
03-18 22:53:17.162 13899-13920/willymatica.alarmapp1 I/System.out﹕ Received string: I4mP4ssw0rd7
03-18 22:53:22.547 13899-13920/willymatica.alarmapp1 I/System.out﹕ Sending string: 7dr0wss4Pm4I
03-18 22:53:22.567 13899-13920/willymatica.alarmapp1 I/System.out﹕ Connected remotely!
03-18 22:53:23.198 13899-13920/willymatica.alarmapp1 I/System.out﹕ Received string: I4mP4ssw0rd7
03-18 22:53:28.933 13899-13920/willymatica.alarmapp1 I/System.out﹕ Sending string: 7dr0wss4Pm4I
03-18 22:53:28.933 13899-13920/willymatica.alarmapp1 I/System.out﹕ Connected remotely!
03-18 22:53:29.113 13899-13920/willymatica.alarmapp1 I/System.out﹕ Received string: I4mP4ssw0rd7
答案 0 :(得分:0)
TCP是面向连接的。建立TCP连接后,您将获得所谓的套接字对。套接字对是源IP地址和源端口以及目标IP地址和目标端口的组合。连接由这4个参数唯一标识。
在整个会话期间,将使用相同的IP地址和端口。
因此,如果一个网络接口不再可用,则会出现问题,因为每个网络接口都有一个IP地址,如果不再可用,则TCP连接不能再选择其他网络接口。
TCP不支持在连接的任何一端更改IP地址。
检测到存在问题需要相当长的时间。您认为您仍然可以发送,但是,TCP将重新传输几次,最终您将看到发送失败。这需要几分钟。根据您的套接字是否阻塞,您会注意到发送将阻止IP @已更改的错误情况。从TCP的角度来看,这就像断线。