LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 855|回复: 4

我刚调通的一个socket tcp通信server端程序,为刚学的人作一点贡献

[复制链接]
发表于 2005-6-8 13:52:32 | 显示全部楼层 |阅读模式
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <errno.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <signal.h>

void sig_chld(int signo)
{
        pid_t pid;
        int stat;
        while((pid = waitpid(-1,&stat,WNOHANG)) > 0);
        return;
}

/*主函数*/
int main(void)
{
        int listenfd,connfd;
        struct sockaddr_in serv_addr,clint_addr;
        //struct hostent *hp;
        //struct servent *sp;

        char szhead[3];
        char szlen[3];
        char szbuf[1025];
        int iDataLen;
        int portnum = 2046;
        int listenqueuenum;
        int len;
        char buf[100];
       


        //初始化socket函数返回一个listen socket //采用IPV4,TCP方式;
                listenfd = socket(AF_INET,SOCK_STREAM,0);
                if(listenfd == -1)
                {
                                perror("error:init socket!");
                                exit(1);
                }
                //初始化结构体
                bzero(&serv_addr,sizeof(serv_addr));
                serv_addr.sin_family = AF_INET;
                serv_addr.sin_port = htons(2046);
                serv_addr.sin_addr.s_addr = INADDR_ANY;
                bzero(&(serv_addr.sin_zero),8);
               
                //memcpy(&serv_addr.sin_addr,*pptr,sizeof(struct in_addr));
               
        //绑定
                if(bind(listenfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) == -1)
                {
                                perror("error:bind socket");
                                exit(1);
                }       
        //侦听
                listenqueuenum = 10;
                if(listen(listenfd,listenqueuenum) == -1)
                {
                                perror("error:listen socket!");
                                exit(1);
                }
                signal(SIGCHLD,sig_chld);
       
        //
        for(;;)
        {
                len =sizeof(clint_addr);
                if((connfd = accept(listenfd,(struct sockaddr *)&clint_addr,&len)) < 0)
                {
                                printf("Accept error:%s\n\a",strerror(errno));
                                perror("accetp error");
                                exit(1);
                }
                /*子进程 */
                /* 复制父进程的所有描述字,所以listenfd connfd 被共享,描述字的访问记数值累计为2*/
                if(fork() == 0)
                {
                        //关闭侦听socket,
                        close(listenfd);
                        printf("connection fron %s, port %d\n",inet_ntop(AF_INET,&clint_addr.sin_addr,buf,sizeof(buf)),ntohs(clint_addr.sin_port));
                        //读取数据
                        recv(connfd,szhead,2,0);
                        recv(connfd,szlen,2,0);
                        iDataLen = 0;
                        szlen[2] = '\n';
                        iDataLen = szlen[0] * 256 + szlen[1];
                        recv(connfd,szbuf,iDataLen,0);
                        //写数据
                        send(connfd,szbuf,iDataLen,0);
                        //处理完成后关闭socket连接
                        close(connfd);
                        //关闭子进程
                        exit(0);
                }
                //父进程关闭 confd ;
                close(connfd);
        }
}
发表于 2005-6-8 14:27:36 | 显示全部楼层
可以改进一下用线程替换进程,这样代价会小些
回复 支持 反对

使用道具 举报

发表于 2005-6-8 23:47:11 | 显示全部楼层
可以改进一下用线程替换进程,这样代价会小些

不知道新的线程库NTPL怎么用?
回复 支持 反对

使用道具 举报

发表于 2005-6-9 00:28:13 | 显示全部楼层
NPTL符合POSIX标准的。
回复 支持 反对

使用道具 举报

发表于 2005-6-9 09:37:45 | 显示全部楼层
NTPL线程库是什么来啊?楼上的兄弟可否介绍一下啊?
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表