[问题] Socket接收资料处理

楼主: TampaBayRays (光芒今年拿冠军)   2018-11-10 10:08:40
开发平台(Platform): (Ex: Win10, Linux, ...)
Mac OS Mojave
编译器(Ex: GCC, clang, VC++...)+目标环境(跟开发平台不同的话需列出)
G++
额外使用到的函数库(Library Used): (Ex: OpenGL, ...)
问题(Question):
我做了一个server想接收client的指令去执行,但是我将指令传到
server时,server无法判断指令,所以我先做了一个小程式,把收到的指令印出来,
并判断他是不是ls,结果还是不行
喂入的资料(Input):
ls
预期的正确结果(Expected Output):
印出recevied:'ls'
yes
错误结果(Wrong Output):
server:
client connected with ip address: 0.0.0.0
received: 'ls
'
received: 'ls
'
client:
telnet 0.0.0.0 8877
Trying 0.0.0.0...
Connected to 0.0.0.0.
Escape character is '^]'.
ls
ls
程式码(Code):(请善用置底文网页, 记得排版,禁止使用图档)
int main(int argc, char *argv[]) {
int SERVER_PORT = 8877;
struct sockaddr_in server_address;
memset(&server_address, 0, sizeof(server_address));
server_address.sin_family = AF_INET;
server_address.sin_port = htons(SERVER_PORT);
server_address.sin_addr.s_addr = htonl(INADDR_ANY);
int listen_sock;
if ((listen_sock = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
printf("could not create listen socket\n");
return 1;
}
if ((bind(listen_sock, (struct sockaddr *)&server_address,sizeof(server_address))) < 0) {
printf("could not bind socket\n");
return 1;
}
int wait_size = 16; // maximum number of waiting clients, after which
// dropping begins
if (listen(listen_sock, wait_size) < 0) {
printf("could not open socket for listening\n");
return 1;
}
struct sockaddr_in client_address;
socklen_t client_address_len = 0;
while (true) {
int sock;
if ((sock =accept(listen_sock, (struct sockaddr *)&client_address, &client_address_len)) < 0) {
printf("could not open a socket to accept data\n");
return 1;
}
int n = 0;
int len = 0, maxlen = 100;
char buffer[maxlen];
char *pbuffer = buffer;
printf("client connected with ip address: %s\n",inet_ntoa(client_address.sin_addr));
while ((n = recv(sock, pbuffer, maxlen, 0)) > 0) {
pbuffer += n;
maxlen -= n;
len += n;
printf("received: '%s'\n", buffer);
string line=buffer;
line=line.substr(0,n);
printf("received: '%s'\n", line.c_str());
if (!strcmp(buffer,"ls")){
printf("yes");
}
if (line=="ls"){
printf("yes");
}
send(sock, buffer, len, 0);
}
close(sock);
}
close(listen_sock);
return 0;
}
补充说明(Supplement):
看起来传回去的东西是没问题的,但是为什么我server收到的东西不太对。
1.右括号被换行了
2.没有判断出我传的是ls(应该要印出yes)
请各位大大救救我QQ
感谢!
作者: bigbite (子子孙孙永保用)   2018-11-10 11:01:00
断行也被传进去了, 改成strncmp(buffer,"ls", 2)
作者: s4300026 (s4300026)   2018-11-10 11:35:00
不是啊,你应该送的时候就把/n处理掉啊,因为你不能保证n=recv会传几个,如果一次只传一个怎办?而不是在收的地方做line的substr的处理那你应该去看client送出前的字串你按enter总是会有接受的buffer吧,在那buffer把/n处理掉那你printf(%d %s, n,buffer)recv后直接印最原始的buffer宣告时 ={}Is/n 另一个猜不出来 /0?char buffer[maxlen] ={};不是啊,你要去看你收到什么东西,才能做处理,如果你要收到什么,就回传什么,那这样写没问题,但是如果你想要判断收到的内容,不是应该收完再处理吗? 也就是要跳出while再处理问题http://beej-zhtw.netdpi.net/07-advanced-technology/7-2-select整串收完再做判断,去看总共收到什么,才去掉不想要的东西然后buffer初始化清零是我想表达的重点是 recv不会一次收完全部的讯息,假设你传 1234567890,但收到的可能会是 1234、567890
作者: Bencrie   2018-11-10 13:12:00
你确定对方 send 会帮你送 \0 吗
作者: JJJJoe (毛毛)   2018-11-10 13:27:00
可以先 line.length() 看看长度多少,如果是 3 的话代表有收到 \0还有 Mac OS 默认的换行符是 \r,所以才会有盖掉第一个字符的情形\r 代表的是返回到该行开头的意思,因此单引号就会回到该行的开头印出,就盖掉原本的字符了我建议使用 line=line.substr(0,line.length()-1) 来处理话说回来 每个系统换行符不同,在其他系统 telnet 结果可能会不一样?你是在substr之后才print的吗?一般来说不会有这个结果@@所以你一开始说length=3是在line=line.substr(0,n-1)还是line=line.substr(0,n)之后?我是指我一开始问的时候,还没有使用line.length()-1我觉得收到的四个字符应该是 ls\r\n 才会有这种情况那我猜的没错,line.length()-2 应该就行了顺便问一下你目前 clinet 是在哪个系统进行的?我想知道的是你是在哪个作业系统下telnet指令的,我不知道每个作业系统有没有差别echo 的讯息如果有换行,就表示有印出\r\n喔喔 看来每个系统的telnet在讯息结尾都会加上\r\n学到一课了XD

Links booklink

Contact Us: admin [ a t ] ucptt.com