VS2008下基于TCP的winsock编程

cjwcommonuse 2013-08-07 12:44:12

#include <stdio.h>
#include <WinSock2.h>

#pragma comment(lib , "ws2_32.lib")

//服务器端
void main()
{
int ret;
WSADATA wsaData;

ret = WSAStartup(0X11 , &wsaData);
if(ret == SOCKET_ERROR)
{
perror("failed to start up");
return;
}

SOCKET server;

server = socket(AF_INET , SOCK_STREAM , 0);

SOCKADDR_IN server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons(8000);

ret = bind(server , (struct sockaddr*)&server_addr , sizeof(server_addr));
if(ret == SOCKET_ERROR)
{
perror("failed to bind");
return;
}

ret = listen(server , 5);

SOCKADDR_IN client_addr;
int addrlen = sizeof(client_addr);
SOCKET connect = 0;
char buf[512];
char sz_ip[20];

while(1)
{
if(connect == 0)
{
connect = accept(server , (struct sockaddr*)&client_addr , &addrlen);
strcpy(sz_ip , inet_ntoa(client_addr.sin_addr));
printf("%s connected\n" , sz_ip);
sprintf(buf , "welcome %s !" , sz_ip);
send(connect , buf , sizeof(buf) , 0);
}
if(recv(connect , buf , 512 , 0) != -1)
printf("%s : %s\n" , sz_ip , buf);
if(strcmp(buf , "$$$"))
closesocket(connect);
}
}

//客户端
//void main()
//{
// int ret;
// WSADATA wsaData;
//
// ret = WSAStartup(0X11 , &wsaData);
// if(ret == SOCKET_ERROR)
// {
// perror("failed to start up");
// return;
// }
//
// SOCKET client;
//
// client = socket(AF_INET , SOCK_STREAM , 0);
//
// SOCKADDR_IN server_addr;
// server_addr.sin_family = AF_INET;
// server_addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
// server_addr.sin_port = htons(8000);
// connect(client , (struct sockaddr*)&server_addr , sizeof(server_addr));
//
// char buf[512] = {0};
//
// recv(client , buf , 512 , 0);
// printf("%s\n" , buf);
// while(strcmp(buf , "$$$") != 0)
// {
// printf("input: ");
// scanf("%s" , buf);
// send(client , buf , strlen(buf)+1 , 0);
// }
// shutdown(client , 0);
// closesocket(client);
// WSACleanup();
//}

运行服务器端后,再运行客户端,然后客户端可以给服务器端发送消息,问题是只有第一次发送的消息服务器端会接受到,之后就再也接收不到了,求解什么原因?
...全文
159 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
max_min_ 2013-08-07
  • 打赏
  • 举报
回复

    while(1)
    {
// accept阻塞等待,等待有客户端连接
        if(connect == 0)
        {
            connect = accept(server , (struct sockaddr*)&client_addr , &addrlen);
            strcpy(sz_ip , inet_ntoa(client_addr.sin_addr));
            printf("%s connected\n" , sz_ip);
            sprintf(buf , "welcome %s !" , sz_ip);
            send(connect , buf , sizeof(buf) , 0);
        }
//有连接上来,调用recv接收一次消息后,
//while循环一次结束,然后在重新accpet,阻塞等待客户端的连接,
//所以每次只能接收一次啦!

        if(recv(connect , buf , 512 , 0) != -1)
            printf("%s : %s\n" , sz_ip , buf);
        if(strcmp(buf , "$$$"))
            closesocket(connect);
    }
上面说了原因, 如果你指向一个客户端连接的话, 改成:


        if(connect == 0)
        {
            connect = accept(server , (struct sockaddr*)&client_addr , &addrlen);
            strcpy(sz_ip , inet_ntoa(client_addr.sin_addr));
            printf("%s connected\n" , sz_ip);
            sprintf(buf , "welcome %s !" , sz_ip);
            send(connect , buf , sizeof(buf) , 0);
        }
 while(1)
    {
        if(recv(connect , buf , 512 , 0) != -1)
            printf("%s : %s\n" , sz_ip , buf);
        if(strcmp(buf , "$$$"))
            closesocket(connect);
    }
如果要多个客户端连接的话, 每个客户端的消息接收处理得需要重新开一个线程或者进程了 因为是要循环接收处理消息的!
赵4老师 2013-08-07
  • 打赏
  • 举报
回复
调试Socket通讯从学用抓包软件开始。
mujiok2003 2013-08-07
  • 打赏
  • 举报
回复
引用 7 楼 cjwcommonuse 的回复:
[quote=引用 4 楼 mujiok2003 的回复:]
 if(connect == 0)
        {
            connect = accept(server , (struct sockaddr*)&client_addr , &addrlen);
            strcpy(sz_ip , inet_ntoa(client_addr.sin_addr));
            printf("%s connected\n" , sz_ip);
            sprintf(buf , "welcome %s !" , sz_ip);
            send(connect , buf , sizeof(buf) , 0);
            connect = 1;
        }
你这是坑害我,connect的值怎么能自己赋值为1?[/quote] 没有看清,sorry. 要使用INVALID_SOCKET, 不要使用0,closesocket之后也要复位。
cjwcommonuse 2013-08-07
  • 打赏
  • 举报
回复
引用 4 楼 mujiok2003 的回复:
 if(connect == 0)
        {
            connect = accept(server , (struct sockaddr*)&client_addr , &addrlen);
            strcpy(sz_ip , inet_ntoa(client_addr.sin_addr));
            printf("%s connected\n" , sz_ip);
            sprintf(buf , "welcome %s !" , sz_ip);
            send(connect , buf , sizeof(buf) , 0);
            connect = 1;
        }
你这是坑害我,connect的值怎么能自己赋值为1?
cjwcommonuse 2013-08-07
  • 打赏
  • 举报
回复
引用 2 楼 hustgonia 的回复:
你喜欢写代码吗?我好象不太喜欢
我喜欢写代码
mujiok2003 2013-08-07
  • 打赏
  • 举报
回复
引用 3 楼 cjwcommonuse 的回复:
[quote=引用 1 楼 max_min_ 的回复:]

    while(1)
    {
// accept阻塞等待,等待有客户端连接
        if(connect == 0)
        {
            connect = accept(server , (struct sockaddr*)&client_addr , &addrlen);
            strcpy(sz_ip , inet_ntoa(client_addr.sin_addr));
            printf("%s connected\n" , sz_ip);
            sprintf(buf , "welcome %s !" , sz_ip);
            send(connect , buf , sizeof(buf) , 0);
        }
//有连接上来,调用recv接收一次消息后,
//while循环一次结束,然后在重新accpet,阻塞等待客户端的连接,
//所以每次只能接收一次啦!

        if(recv(connect , buf , 512 , 0) != -1)
            printf("%s : %s\n" , sz_ip , buf);
        if(strcmp(buf , "$$$"))
            closesocket(connect);
    }
上面说了原因, 如果你指向一个客户端连接的话, 改成:


        if(connect == 0)
        {
            connect = accept(server , (struct sockaddr*)&client_addr , &addrlen);
            strcpy(sz_ip , inet_ntoa(client_addr.sin_addr));
            printf("%s connected\n" , sz_ip);
            sprintf(buf , "welcome %s !" , sz_ip);
            send(connect , buf , sizeof(buf) , 0);
        }
 while(1)
    {
        if(recv(connect , buf , 512 , 0) != -1)
            printf("%s : %s\n" , sz_ip , buf);
        if(strcmp(buf , "$$$"))
            closesocket(connect);
    }
如果要多个客户端连接的话, 每个客户端的消息接收处理得需要重新开一个线程或者进程了 因为是要循环接收处理消息的!
谢谢你的帮助。我找到问题了。是因为服务器端每次循环会关闭socket这样就好啦。
	
while(1)
	{
		if(connect == 0)
		{
			connect = accept(server , (struct sockaddr*)&client_addr , &addrlen);
			strcpy(sz_ip , inet_ntoa(client_addr.sin_addr));
			printf("%s connected\n" , sz_ip);
			sprintf(buf , "welcome %s !" , sz_ip);
			send(connect , buf , sizeof(buf) , 0);
		}
		if(recv(connect , buf , 512 , 0) != -1)
			printf("%s : %s\n" , sz_ip , buf);
		if(strcmp(buf , "$$$") == 0) //之前这里的判断条件反了
		{
			closesocket(connect);
			connect = 0;
		}
	}
[/quote] 呵呵。
mujiok2003 2013-08-07
  • 打赏
  • 举报
回复
 if(connect == 0)
        {
            connect = accept(server , (struct sockaddr*)&client_addr , &addrlen);
            strcpy(sz_ip , inet_ntoa(client_addr.sin_addr));
            printf("%s connected\n" , sz_ip);
            sprintf(buf , "welcome %s !" , sz_ip);
            send(connect , buf , sizeof(buf) , 0);
            connect = 1;
        }
cjwcommonuse 2013-08-07
  • 打赏
  • 举报
回复
引用 1 楼 max_min_ 的回复:

    while(1)
    {
// accept阻塞等待,等待有客户端连接
        if(connect == 0)
        {
            connect = accept(server , (struct sockaddr*)&client_addr , &addrlen);
            strcpy(sz_ip , inet_ntoa(client_addr.sin_addr));
            printf("%s connected\n" , sz_ip);
            sprintf(buf , "welcome %s !" , sz_ip);
            send(connect , buf , sizeof(buf) , 0);
        }
//有连接上来,调用recv接收一次消息后,
//while循环一次结束,然后在重新accpet,阻塞等待客户端的连接,
//所以每次只能接收一次啦!

        if(recv(connect , buf , 512 , 0) != -1)
            printf("%s : %s\n" , sz_ip , buf);
        if(strcmp(buf , "$$$"))
            closesocket(connect);
    }
上面说了原因, 如果你指向一个客户端连接的话, 改成:


        if(connect == 0)
        {
            connect = accept(server , (struct sockaddr*)&client_addr , &addrlen);
            strcpy(sz_ip , inet_ntoa(client_addr.sin_addr));
            printf("%s connected\n" , sz_ip);
            sprintf(buf , "welcome %s !" , sz_ip);
            send(connect , buf , sizeof(buf) , 0);
        }
 while(1)
    {
        if(recv(connect , buf , 512 , 0) != -1)
            printf("%s : %s\n" , sz_ip , buf);
        if(strcmp(buf , "$$$"))
            closesocket(connect);
    }
如果要多个客户端连接的话, 每个客户端的消息接收处理得需要重新开一个线程或者进程了 因为是要循环接收处理消息的!
谢谢你的帮助。我找到问题了。是因为服务器端每次循环会关闭socket这样就好啦。
	
while(1)
	{
		if(connect == 0)
		{
			connect = accept(server , (struct sockaddr*)&client_addr , &addrlen);
			strcpy(sz_ip , inet_ntoa(client_addr.sin_addr));
			printf("%s connected\n" , sz_ip);
			sprintf(buf , "welcome %s !" , sz_ip);
			send(connect , buf , sizeof(buf) , 0);
		}
		if(recv(connect , buf , 512 , 0) != -1)
			printf("%s : %s\n" , sz_ip , buf);
		if(strcmp(buf , "$$$") == 0) //之前这里的判断条件反了
		{
			closesocket(connect);
			connect = 0;
		}
	}
hustgonia 2013-08-07
  • 打赏
  • 举报
回复
你喜欢写代码吗?我好象不太喜欢

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧