C中的TCP客户端和服务器

时间:2015-03-05 12:29:01

标签: c tcp client server

我在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;
}

1 个答案:

答案 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()中的文件描述符。