LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
楼主: nm47622791

请大虾指导一个socket问题

[复制链接]
发表于 2003-8-20 16:44:46 | 显示全部楼层
fork()产生的是多进程程序,不 是线程。
我在你贴出来的程序中加上 printf("child process success!\n"),结果一切正常。
 楼主| 发表于 2003-8-20 17:37:55 | 显示全部楼层

我发现了

我刚才在单步调试,好像是一直等到输出十编accept one connect! recieve a connection from ...才开一个新进程.我不明白为什么?
    请版主再帮我看看!麻烦您了!
发表于 2003-8-20 19:30:04 | 显示全部楼层
你把socket中的客户端口打印出来看看有什么变化。
 楼主| 发表于 2003-8-21 09:45:32 | 显示全部楼层

怎么打印socket中的客户端口?

需要什么操作?我是初学的好多不懂.
 楼主| 发表于 2003-8-21 10:58:21 | 显示全部楼层

版主大兄

我直接用ping,ping出 www.163.com 的IP.我能不能用这个IP直接connect来测试我的代理程序?我刚才试了下好像有问题.这种做法对不?
谢谢版主!
 楼主| 发表于 2003-8-21 11:00:48 | 显示全部楼层

我的全部程序

[php]
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>

#define LISTENIEPORT 3333
#define SERVERPORT 80
#define TRANSPORT 3334
#define BACKLOG 10
#define SERVERADDR "202.108.36.167"//www.163.com

struct sockaddr_in server_addr;

void proxy(int usersock);

main()
{
        int listeniesock,transock;//listenie and transinfo socket
        struct sockaddr_in local_addr;//local IP information
        struct sockaddr_in remote_addr;//remote client IE IP information
       // struct sockaddr_in server_addr;//remote server IP information

        //fill the remote server address
        bzero((char *)&server_addr,sizeof(server_addr));
        server_addr.sin_family=AF_INET;
        server_addr.sin_port=htons(SERVERPORT);
        server_addr.sin_addr.s_addr=htonl(SERVERADDR);
        //create listenie socket
        if((listeniesock=socket(AF_INET,SOCK_STREAM,0))==-1)
        {
                perror("socket create error!");
                exit(1);
        }
        printf("create socket OK!\n");
        bzero((char *)&local_addr,sizeof(local_addr));
        printf("bzero OK!\n");
        local_addr.sin_family=AF_INET;
        printf("local family AF_INET OK!\n");
        local_addr.sin_port=htons(LISTENIEPORT);
        printf("local port OK!\n");
        //local_addr.sin_addr.s_addr=inet_addr("182.4.1.26");
        local_addr.sin_addr.s_addr=htonl(INADDR_ANY);
        printf("local address is %s\n",inet_ntoa(local_addr.sin_addr));
        //bzero(&(local_addr.sin_zero),8);
        //memset(&(local_addr.sin_zero),0,sizeof(local_addr.sin_zero));
        //bind listenie socket
        //printf("bzero OK!");
        if((bind(listeniesock,(struct sockaddr_in *)&local_addr,sizeof(struct sockaddr_in)))<0)
        {
                printf("error!\n");
                perror("bind error!\n");
                exit(1);
        }
        printf("bind socket OK!\n");
        //listen IE request
        if(listen(listeniesock,BACKLOG)==-1)
        {
                perror("listen error!\n");
                exit(1);
        }
        printf("listening......\n");

        while(1)
        {
                int sin_size=sizeof(remote_addr);
                if((transock=accept(listeniesock,(struct sockaddr_in *)&remote_addr,&sin_size))==-1)
                {
                        perror("accept error!\n");
                        continue;
                }
               // printf("accept one connet!\n");
                printf("recieved a connection from %s\n",inet_ntoa(remote_addr.sin_addr));
                if(!fork())
                {
                        //child process code segment
                        close(listeniesock);
                         proxy(transock);
                         exit(0);
                        printf("child process success!\n");
                         

                }
                close(transock);
        }
}

void proxy(int usersock)
{
        int connectsock;//connect server socket
        int connstat;//the connection status
        int iolen;//the length of write or read data
        char buf[2048];//the buffer
        fd_set rdfdset;

        if((connectsock=socket(AF_INET,SOCK_STREAM,0))==-1)perror("connect socket create error!\n");
        connstat=connect(connectsock,(struct sockaddr_in *)&server_addr,sizeof(server_addr));
        switch(connstat)
        {
                case 0:break;
                case ETIMEDOUT:
                case ECONNREFUSED:
                case ENETUNREACH:
                       close(usersock);
                       perror("connect error!\n");
                       exit(1);
                       break;
                default:perror("failed to connect to host!\n");
        }
        while(1)
        {
                FD_ZERO(&rdfdset);
                FD_SET(usersock,&rdfdset);
                FD_SET(connectsock,&rdfdset);
                if(select(FD_SETSIZE,&rdfdset,NULL,NULL,NULL)<0)perror("select failed!\n");
                if(FD_ISSET(usersock,&rdfdset))
                {
                        if((iolen=read(usersock,buf,sizeof(buf)))<=0)break;
                        write(connectsock,buf,iolen);
                }
                if(FD_ISSET(connectsock,&rdfdset))
                {
                        if((iolen=read(connectsock,buf,sizeof(buf)))<=0)break;
                        write(usersock,buf,iolen);
                }
        }
        close(connectsock);
        close(usersock);                               
}
[/php]
 楼主| 发表于 2003-8-21 16:34:07 | 显示全部楼层

迷惑

这个程序中的main()函数里在接受连接后为什么没有直接开一个新进程,而是执行了后面的close(transock)?在这样执行了十次后,才开了个新线程,这时早已关闭了transock,里面的proxy(transock)函数无法正确运行,程序就死在这里了.
   望高手和大虾解答小弟心中的疑惑!谢谢!
发表于 2003-8-21 16:56:34 | 显示全部楼层
我的输出如下,不过代理还是用不成
create socket OK!
bzero OK!
local family AF_INET OK!
local port OK!
local address is 0.0.0.0
bind socket OK!
listening......
recieved a connection from 192.168.6.19
child process success!
recieved a connection from 192.168.6.19
child process success!
recieved a connection from 192.168.6.19
child process success!
recieved a connection from 192.168.6.19
child process success!
 楼主| 发表于 2003-8-21 17:02:37 | 显示全部楼层

请问

是我的代理函数有问题吗?我的连child process success!都输不出来!
谢谢指导!期待您的指导!
发表于 2003-8-21 17:06:34 | 显示全部楼层
程序有些地方有问题,
server_addr.sin_addr.s_addr=htonl(SERVERADDR);
改成
inet_aton(SERVERADDR, &server_addr.sin_addr);
三个(struct sockaddr_in *)改成(struct sockaddr *)

HTTP应该是客户端发出一个"GET /HTTP/1.0 \n\n"再关闭套接口的写端shutdown(sockfd, 1),完了以后读数据,估计代理不成功可能和HTTP协议有关(没有关闭写端)。

还有把
exit(0);
printf("child process success!\n");
交换一下,printf应该在exit前面。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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