linux socket客户端/服务器程序

时间:2014-03-18 20:11:27

标签: c linux sockets

您好我的服务器程序是:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main()
{
    int sfd, cfd;
    int ch='k';
    struct sockaddr_in saddr, caddr;

    sfd= socket(AF_INET, SOCK_STREAM, 0);
    saddr.sin_family=AF_INET;           /* Set Address Family to Internet */
    saddr.sin_addr.s_addr=htonl(INADDR_ANY);    /* Any Internet address */
    saddr.sin_port=htons(29008);            /* Set server port to 29008 */
                        /* select any arbitrary Port >1024                */
    bind(sfd, (struct sockaddr *)&saddr, sizeof(saddr));
    listen(sfd, 1);
    while(1) {
            printf("Server waiting...");
            cfd=accept(sfd, (struct sockaddr *)NULL, NULL);
            if(read(cfd, &ch, 1)<0) perror("read");
            ch++;
            if(write(cfd, &ch, 1)<0) perror("write");
            close(cfd);
    }
}

所以我有一个简单的服务器程序,我也有一个客户端程序。我遇到的问题是,当我在不同终端上的同一台机器上运行时,客户端输出工作正常。服务器虽然没有打印等待线,但它堆叠使我无法使用终端。问题是什么?

1 个答案:

答案 0 :(得分:2)

正如评论所指出的,您需要发送新行或fflush(stdout)以使服务器打印出您想要的内容,或者在操作stdout之前完全禁用缓冲:setbuf(stdout, NULL)没有必要。默认情况下,stdout是行缓冲的,stderr是无缓冲的。请注意,Microsoft运行时库不支持行缓冲,因此如果使用Winsock实现此程序,它将立即打印。
bind()之前,您可以设置SO_REUSEADDR选项,以便在程序不正常退出时(在上面的代码中,您没有显式关闭侦听套接字sfd,尽管操作系统将在终止时清理,但这样做是一种很好的做法),可以立即重新使用可能保持TIME_WAIT状态的端口。

int yes = 1;
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) 

如果要在运行程序后使用当前终端,请在命令后添加&,以便程序在后台运行。