我在C中创建了一个TCP客户端和一个服务器,并在两个终端中执行它。但在更改和编译代码后,我无法获得输出。服务器和客户端都继续运行并且什么都不打印
这是我的服务器代码
/* Sample TCP server */
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <string.h>
int fsize(FILE *fp){
int prev=ftell(fp);
fseek(fp, 0L, SEEK_END);
int sz=ftell(fp);
fseek(fp,prev,SEEK_SET); //go back to where we were
return sz;
}
int main(int argc, char**argv)
{
int listenfd,connfd,n, length;
struct sockaddr_in servaddr,cliaddr;
socklen_t clilen;
char* banner = "ack";
char buffer[1000];
/* one socket is dedicated to listening */
listenfd=socket(AF_INET,SOCK_STREAM,0);
/* initialize a sockaddr_in struct with our own address information for binding the socket */
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
servaddr.sin_port=htons(32000);
/* binding */
bind(listenfd,(struct sockaddr *)&servaddr,sizeof(servaddr));
listen(listenfd,0);
clilen=sizeof(cliaddr);
while(1){
/* accept the client with a different socket. */
connfd = accept(listenfd,(struct sockaddr *)&cliaddr,&clilen);
// the uninitialized cliaddr variable is filled in with the
n = recvfrom(connfd,buffer,1000,0,(struct sockaddr *)&cliaddr,&clilen);//information of the client by recvfrom function
buffer[n] = 0;
sendto(connfd,banner,strlen(banner),0,(struct sockaddr *)&cliaddr,sizeof(cliaddr));
printf("Received:%s\n",buffer);
FILE *fp = fopen("serverfile.txt", "r");
length = fsize(fp);
printf("%d\n", length);
}
return 0;
}
这是我的客户代码
/* Sample TCP client */
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <string.h>
int main(int argc, char**argv)
{
int sockfd,n;
struct sockaddr_in servaddr;
char banner[] = "Hello TCP server! This is TCP client";
char buffer[1000];
if (argc != 2)
{
printf("usage: ./%s <IP address>\n",argv[0]);
return -1;
}
/* socket to connect */s
sockfd=socket(AF_INET,SOCK_STREAM,0);
/* IP address information of the server to connect to */
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr=inet_addr(argv[1]);
servaddr.sin_port=htons(32000);
connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
sendto(sockfd,banner,strlen(banner),0, (struct sockaddr*)&servaddr,sizeof(servaddr));
n=recvfrom(sockfd,buffer,10000,0,NULL,NULL);
buffer[n]=0;
printf("Received:%s\n",buffer);
return 0;
}
答案 0 :(得分:1)
您的主要问题是您没有检查套接字上的任何操作的结果,因此服务器或客户端完全有可能报告错误消息,使您的问题的答案显而易见。
特别是,如果服务器无法绑定或侦听侦听套接字,它将进入无限循环,使得失败的接受,读取和写入永远。
我怀疑,当您重新启动服务器时,前一个套接字仍然处于TIME_WAIT状态,因此它无法绑定到该端口。您可以在创建套接字后使用以下内容解决此问题:
int reuseaddr = 1;
if (setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,&reuseaddr,sizeof(reuseaddr))==-1)
{
fprintf(stderr, "%s",strerror(errno));
exit(1);
}
请注意上述内容如何检查返回结果并报告失败时的错误。每次致电socket()
,listen()
,bind()
,connect()
,recvfrom()
,sendto()
和{{1}后,您需要执行此操作或类似操作}}
注意,我如何将close()
放入该列表中。当你完成它时,你真的必须在连接套接字上调用它,特别是在服务器上,否则你将泄漏close()
中的文件描述符。