所以这是TCP echo客户端的代码。当我让echo服务器侦听端口5000时,客户端连接但是一旦我键入消息并按Enter键,它会自动断开连接。这有什么问题?
源代码(tcp_ec.c):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <netdb.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#define MAX_BUFFER 1024
void die(char *s)
{
perror(s);
exit(1);
}
int main()
{
int connector,flags,r;
int port;
struct hostent* host;
struct in_addr in;
struct sockaddr_in rmaddr;
bool connected = false;
char sndbuffer[MAX_BUFFER];
char rcvbuffer[MAX_BUFFER];
char hostname[INET_ADDRSTRLEN];
char* exit = "quit";
if((connector = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))<0){
perror("socket");
return -1;
}
printf("\n");
printf("Enter the remote hostname(URL/IP4 address): ");
scanf("%s", hostname);
printf("\n");
printf("Enter the port number you wish to connect(on): ");
scanf("%u", &port);
printf("\n");
if(port==0){
printf("ERR0R: Port number must be between 1 & 65,535\n");
printf("\n");
printf("Enter the port number you wish to connect(on): ");
scanf("%u", &port);
printf("\n");
}
host = gethostbyname(hostname);
if(host==NULL){
perror("hostname");
return -1;
}
bzero(&rmaddr,sizeof(rmaddr));
rmaddr.sin_family = AF_INET;
rmaddr.sin_port = htons(port);
bcopy((char*)host->h_addr, (char*)&rmaddr.sin_addr.s_addr, host->h_length);
if(connect(connector,(struct sockaddr*)&rmaddr,sizeof(rmaddr))<0){
perror("connect");
return -1;
}else{
connected=true;
printf("\n");
printf("Connected to host: %s",hostname,"on port %u",port);
printf(" type 'quit' to disconnect\n");
printf("\n");
}
while(connected==true){
printf(">");
scanf("%s",sndbuffer);
printf("\n");
if(sndbuffer==exit){
close(connector);
connected = false;
return 0;
}
if(send(connector,(void*)sndbuffer,sizeof(sndbuffer),MSG_EOR||MSG_NOSIGNAL)<0){
perror("send");
close(connector);
return -1;
}
if(recv(connector,(void*)rcvbuffer,sizeof(rcvbuffer),MSG_EOR||MSG_NOSIGNAL)<0){
perror("recv");
close(connector);
return -1;
}else{
printf(">>");
printf("%s\n",rcvbuffer);
printf("\n");
}
}
}
控制台输出(程序输出文件为“tc”):
zermacr0yd@DALEK /usr/lib/gcc/x86_64-linux-gnu/4.7.3/include $ ./tec
Enter the remote hostname(URL/IP4 address): 127.0.0.1
Enter the port number you wish to connect(on): 5000
Connected to host: 127.0.0.1 type 'quit' to disconnect
>asssr
sendmsg: Broken pipe
zermacr0yd@DALEK /usr/lib/gcc/x86_64-linux-gnu/4.7.3/include $
当echo_server在端口5000上运行时,这样做。
答案 0 :(得分:0)
替换:
if(send(connector,(void*)sndbuffer,sizeof(sndbuffer),MSG_EOR||MSG_NOSIGNAL)<0){
... and
if(recv(connector,(void*)rcvbuffer,sizeof(rcvbuffer),MSG_EOR||MSG_NOSIGNAL)<0){
人:
if(send(connector,(void*)sndbuffer,sizeof(sndbuffer),MSG_EOR|MSG_NOSIGNAL)<0){
... and
if(recv(connector,(void*)rcvbuffer,sizeof(rcvbuffer),MSG_EOR|MSG_NOSIGNAL)<0){
...加上一些小错误。
编辑:完整更正的来源
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <netdb.h>
#include <stdbool.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#define MAX_BUFFER 1024
void die(char *s)
{
perror(s);
exit(1);
}
int main() {
int connector,flags,r;
int port;
struct hostent* host;
struct in_addr in;
struct sockaddr_in rmaddr;
bool connected = false;
char sndbuffer[MAX_BUFFER];
char rcvbuffer[MAX_BUFFER];
char hostname[INET_ADDRSTRLEN];
char* exit = "quit";
if((connector = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))<0){
perror("socket");
return -1;
}
printf("\n");
printf("Enter the remote hostname(URL/IP4 address): ");
scanf("%s", hostname);
printf("\n");
printf("Enter the port number you wish to connect(on): ");
scanf("%u", &port);
printf("\n");
if(port==0){
printf("ERR0R: Port number must be between 1 & 65,535\n");
printf("\n");
printf("Enter the port number you wish to connect(on): ");
scanf("%u", &port);
printf("\n");
}
host = gethostbyname(hostname);
if(host==NULL){
perror("hostname");
return -1;
}
bzero(&rmaddr,sizeof(rmaddr));
rmaddr.sin_family = AF_INET;
rmaddr.sin_port = htons(port);
bcopy((char*)host->h_addr, (char*)&rmaddr.sin_addr.s_addr, host->h_length);
if(connect(connector,(struct sockaddr*)&rmaddr,sizeof(rmaddr))<0){
perror("connect");
return -1;
}else{
// connected=true;
printf("\n");
printf("Connected to host: %son port %u", hostname, port);
printf(" type 'quit' to disconnect\n");
printf("\n");
}
// while(connected==true){
while(1){
printf(">");
scanf("%s",sndbuffer);
printf("\n");
if(sndbuffer==exit){
close(connector);
// connected = false;
return 0;
}
if(send(connector,(void*)sndbuffer,sizeof(sndbuffer),MSG_EOR|MSG_NOSIGNAL)<0){
perror("send");
close(connector);
return -1;
}
if(recv(connector,(void*)rcvbuffer,sizeof(rcvbuffer),MSG_EOR|MSG_NOSIGNAL)<0){
perror("recv");
close(connector);
return -1;
}else{
printf(">>");
printf("%s\n",rcvbuffer);
printf("\n");
}
}
return 0;
}
输出:
~/src/usenet$ ./a.out
Enter the remote hostname(URL/IP4 address): 127.0.0.1
Enter the port number you wish to connect(on): 7
Connected to host: 127.0.0.1on port 7 type 'quit' to disconnect
>aap
>>aap
>noot
>>noot
>mies
>>mies
>quit
>>quit
>^C
[对“退出”没有反应是由于缺少strncmp()// memcmp(),加上“quit is really”quit \ n“(并且不是nul-terminated)]
答案 1 :(得分:0)
我认为这个问题与Byte Ordering函数有关,因为我注意到添加标题会产生编译器警告。但事实证明,首先是导致问题的原因,以及调用bind的事实( )echo服务器应用程序中的函数给出了一个EONOTSUPP错误,就是套接字没有绑定到特定的地址!它绑定到所有地址,此GCC错误已记录在 Here 。所以现在手头的任务是下载和安装补丁,我会从那里看到它是如何工作的。
答案 2 :(得分:0)
我之前看到,连接()到127.0.0.1上不存在的端口可以成功返回,但它已经存在了几十年,而不是在Linux上。我之后使用的技术是进行零长度写入,如果连接没有真正起作用,则会失败。我从来没有触及它的底部,我已经有20多年没有看到这个问题了。
但你的代码有其他问题。
你忽略'recv()'返回的计数,除非它是否定的。这有两个后果:
您还发送垃圾。在这种情况下,你提供给send()的计数应该是'strlen(sndbuffer)'而不是'sizeof sndbuffer',因为你刚刚读了一个带有'fgets()'的以null结尾的字符串。