免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1403 | 回复: 4
打印 上一主题 下一主题

急!socket高手请进! [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2004-07-14 10:37 |只看该作者 |倒序浏览
小弟初学socket编程,现在遇到了这样的问题。
  当client连接上server后,使用recv接收server发过来的数据,但却无法recv返回,看了书以后知道这是因为recv没有收到足够的数据所以不能返回,但是在windows下的C/S不管是否有足够的数据,也能收到程序中的缓冲区中,但如果windows与solaris通讯,似乎收不到数据?
  代码如下,请高手指点!



[client.c]
#include "stdafx.h"
#include "winsock2.h"

int main(int argc, char* argv[])
{
        WSADATA wData;
        SOCKET sClient;
        struct sockaddr_in sinServer;
        unsigned short iPort=34910;
        char sbuffer[30];
        char rbuffer[30];
        int rx_bytes=-1;

        unsigned long ul=1;
        int nRet;
       
       
       
        memset((void *)sbuffer,0,sizeof(sbuffer));
        memset((void *)rbuffer,0,sizeof(rbuffer));
        printf("%s\n",sbuffer);

        if(WSAStartup(MAKEWORD(2,2),&wData)!=0)
        {
                printf("Failed to load Winsock!\n";
                return 1;
        }

        sinServer.sin_family=AF_INET;
        sinServer.sin_port=htons(iPort);
        sinServer.sin_addr.s_addr=inet_addr("192.168.2.102";

        sClient=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);

       
       
        connect(sClient,(struct sockaddr *)&sinServer,sizeof(sServer));
        printf("connect error code is  %d\t\n",WSAGetLastError());

       

        sprintf(sbuffer,"This is a test!";
        printf("%s\n",sbuffer);
       
        send(sClient,sbuffer,strlen(sbuffer),0);
        printf("send error code is  %d\t\n",WSAGetLastError());
       
        printf("begin receive!\n";
        while(1)
        {
        recv(sClient,rbuffer,30,0);
        printf("receive error code is  %d\t\n",WSAGetLastError());
        printf("%d",rx_bytes);


        printf("%s\n",rbuffer);
        }
        return 0;
}



[server.c]
#include <stdio.h>;
#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>;
#include <netdb.h>;
#include <signal.h>;
#define MYPORT 34910
#define BACKLOG 10

int n;
char buf[2048];
char buf1[]="this is test!\n";

void main()
{
        int listenfd,new_fd;
        struct sockaddr_in my_addr;
        struct sockaddr_in their_addr;
        int sin_size;
       
        if ((listenfd=socket(AF_INET,SOCK_STREAM,0))==-1)
        {
                perror("socket";
                exit(1);
        }
       
        bzero(&(my_addr),sizeof(my_addr));
        my_addr.sin_family=AF_INET;
        my_addr.sin_port=htons(MYPORT);
        my_addr.sin_addr.s_addr=INADDR_ANY;
       
        if ((bind(listenfd,(struct sockaddr*)&my_addr,sizeof(struct sockaddr))==-1))
        {
                perror("bind";
                exit(1);
        }
       
        if (listen(listenfd,BACKLOG)==-1)
        {
                perror("listen";
                exit(1);
        }
       
               
        while(1)
        {
                sin_size=sizeof(struct sockaddr_in);
                if ((new_fd==accept(listenfd,(struct sockaddr*)&their_addr,&sin_size))==-1)
                {
                        if (errno==EINTR)
                        continue;
                        perror("accept";
                        continue;
                }
                printf("server:got connection form %s\n",inet_ntoa(their_addr.sin_addr));
                write(new_fd,buf1,strlen(buf1));
                close(new_fd);
        }
}

client.c环境:windows XP+Visual C++
server.c环境:solaris 9+Forte C

论坛徽章:
0
2 [报告]
发表于 2004-07-14 11:40 |只看该作者

急!socket高手请进!

去看看书上关于阻塞与非阻塞SOCKET部分。

论坛徽章:
0
3 [报告]
发表于 2004-07-14 17:19 |只看该作者

急!socket高手请进!

client端期望得到30个字节
recv(sClient,rbuffer,30,0);

server端只给了不到30个字节长的字符串
char buf1[]="this is test!\n";
write(new_fd,buf1,strlen(buf1));

而且两边通信完成后最好都shutdown一下.

论坛徽章:
0
4 [报告]
发表于 2004-07-14 17:42 |只看该作者

急!socket高手请进!

你那是Recv函数阻塞了,可以使用select()函数来解决套节字阻塞的问题.
下面是select()函数用法:
while(1)
                WaitTime.tv_sec = 1;
                WaitTime.tv_usec = 0;
                FD_ZERO(&BReadSet);
                FD_SET((unsigned int)ConBankid, &BReadSet);
                if(select(ConBankid + 1, &BReadSet, NULL, NULL, &WaitTime) <=0) {
                    printf("not recv message of TranceKey from yl!\n";
                    continue;
                }
                if(FD_ISSET(ConBankid, &BReadSet)) {
                    ylrecvid = Bank_Recv(ConBankid, RecvylBuf);
                }
}

注解:select(ConBankid + 1, &BReadSet, NULL, NULL, &WaitTime)
   参数:
   1.ConBankid 为socket返回的ID
   2.&BReadSet接收数据状态
  3.NULL,发送数据状态,我这里没有用到
  4.NULL,socket的状态
  5.WaitTime.监控socket时间间隔.

论坛徽章:
0
5 [报告]
发表于 2004-07-15 09:44 |只看该作者

急!socket高手请进!

谢谢guoysheng,samhoo与windflowers1976!

正在继续调试中……
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP