第2次 数据从客户端发出后 服务器就收不到了代码如下
// CSocketSev.cpp : 定义控制台应用程序的入口点。
//#include "stdafx.h"
#include <winsock.h>
#include <iostream>
#pragma comment( lib,"Ws2_32.lib")
#define DEFAULT_PORT 2000
SOCKET m_Listening;int Receive(SOCKET fd,char *szText,int len)
{
int cnt, rc;
cnt=len;
while(cnt>0)
{
rc=recv(fd,szText,cnt,0);
if(rc==SOCKET_ERROR)
{
return -1;
}
if(rc==0)
return len-cnt;
szText+=rc;
cnt-=rc;
}
return len;
}int Send(SOCKET fd,char *szText,int len)
{
int cnt, rc;
cnt=len;
while(cnt>0)
{
rc=send(fd,szText,cnt,0);
if(rc==SOCKET_ERROR)
{
return -1;
}
if(rc==0)
return len-cnt;
szText+=rc;
cnt-=rc;
}
return len;
}
DWORD WINAPI ListenThread(LPVOID lpparam)
{
SOCKET Listening = m_Listening;
//开始监听是否有客户端连接。
if(listen(Listening,40) == SOCKET_ERROR)
{
return 0;
}
char szBuf[MAX_PATH];
//初始化
memset(szBuf,0,MAX_PATH);
while(1)
{
SOCKET ConnectSocket;
sockaddr_in ClientAddr;
int nLen = sizeof(sockaddr);
//阻塞直到有客户端连接,不然多浪费CPU资源。
ConnectSocket = accept(Listening,(sockaddr*)&ClientAddr,&nLen);
//都到客户端的IP地址。
char *pAddrname = inet_ntoa(ClientAddr.sin_addr);
Receive(ConnectSocket,szBuf,100);
//界面上显示请求数据。
strcat(szBuf,"来自(");
strcat(szBuf,pAddrname);
strcat(szBuf,")");
//向客户端发送回应数据
Send(ConnectSocket,szBuf,100);
puts(szBuf);
}
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
WSADATA wsaData;
if(WSAStartup(0x0110,&wsaData)) //调用Windows Sockets DLL
{
puts("Winsock无法初始化!");
return -1;
}
DWORD dwThreadID = 0;
sockaddr_in local;
//DWORD dwThreadID = 0;
local.sin_family=AF_INET;
//设置的端口为DEFAULT_PORT。
/*if(argc>0)
{
local.sin_port = htons(argv[0]);
}
else
{
local.sin_port=htons(DEFAULT_PORT);
}*/
local.sin_port=htons(DEFAULT_PORT);
//IP地址设置成INADDR_ANY,让系统自动获取本机的IP地址。
local.sin_addr.S_un.S_addr=INADDR_ANY;//inet_addr("127.0.0.1");
//初始化Socket
m_Listening=socket(AF_INET,SOCK_STREAM,0);
if(m_Listening == INVALID_SOCKET)
{
puts("创建Winsock实例失败!");
return -1;
}
if(bind(m_Listening,(LPSOCKADDR)&local,sizeof(local)) == SOCKET_ERROR )
{
closesocket(m_Listening);
puts("绑定端口失败!");
return -1;
}
//THREAD m_hListenThread;
//m_hListenThread = ::CreateThread(NULL,0,ListenThread,this,0,&dwThreadID);
if(listen(m_Listening,40) == SOCKET_ERROR)
{
puts("监听端口失败!");
return -1;
}
puts("启动成功");
char szBuf[MAX_PATH];
//初始化
memset(szBuf,0,MAX_PATH);
while(1)
{
SOCKET ConnectSocket;
sockaddr_in ClientAddr;
int nLen = sizeof(sockaddr);
//阻塞直到有客户端连接,不然多浪费CPU资源。
ConnectSocket = accept(m_Listening,(sockaddr*)&ClientAddr,&nLen);
//都到客户端的IP地址。
char *pAddrname = inet_ntoa(ClientAddr.sin_addr);
Receive(ConnectSocket,szBuf,100);
//向客户端发送回应数据
Send(ConnectSocket,szBuf,100);
//界面上显示请求数据。
strcat(szBuf,"\t来自(");
strcat(szBuf,pAddrname);
strcat(szBuf,")");
//closesocket(ConnectSocket);
puts(szBuf);
}
}
// CSocketSev.cpp : 定义控制台应用程序的入口点。
//#include "stdafx.h"
#include <winsock.h>
#include <iostream>
#pragma comment( lib,"Ws2_32.lib")
#define DEFAULT_PORT 2000
SOCKET m_Listening;int Receive(SOCKET fd,char *szText,int len)
{
int cnt, rc;
cnt=len;
while(cnt>0)
{
rc=recv(fd,szText,cnt,0);
if(rc==SOCKET_ERROR)
{
return -1;
}
if(rc==0)
return len-cnt;
szText+=rc;
cnt-=rc;
}
return len;
}int Send(SOCKET fd,char *szText,int len)
{
int cnt, rc;
cnt=len;
while(cnt>0)
{
rc=send(fd,szText,cnt,0);
if(rc==SOCKET_ERROR)
{
return -1;
}
if(rc==0)
return len-cnt;
szText+=rc;
cnt-=rc;
}
return len;
}
DWORD WINAPI ListenThread(LPVOID lpparam)
{
SOCKET Listening = m_Listening;
//开始监听是否有客户端连接。
if(listen(Listening,40) == SOCKET_ERROR)
{
return 0;
}
char szBuf[MAX_PATH];
//初始化
memset(szBuf,0,MAX_PATH);
while(1)
{
SOCKET ConnectSocket;
sockaddr_in ClientAddr;
int nLen = sizeof(sockaddr);
//阻塞直到有客户端连接,不然多浪费CPU资源。
ConnectSocket = accept(Listening,(sockaddr*)&ClientAddr,&nLen);
//都到客户端的IP地址。
char *pAddrname = inet_ntoa(ClientAddr.sin_addr);
Receive(ConnectSocket,szBuf,100);
//界面上显示请求数据。
strcat(szBuf,"来自(");
strcat(szBuf,pAddrname);
strcat(szBuf,")");
//向客户端发送回应数据
Send(ConnectSocket,szBuf,100);
puts(szBuf);
}
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
WSADATA wsaData;
if(WSAStartup(0x0110,&wsaData)) //调用Windows Sockets DLL
{
puts("Winsock无法初始化!");
return -1;
}
DWORD dwThreadID = 0;
sockaddr_in local;
//DWORD dwThreadID = 0;
local.sin_family=AF_INET;
//设置的端口为DEFAULT_PORT。
/*if(argc>0)
{
local.sin_port = htons(argv[0]);
}
else
{
local.sin_port=htons(DEFAULT_PORT);
}*/
local.sin_port=htons(DEFAULT_PORT);
//IP地址设置成INADDR_ANY,让系统自动获取本机的IP地址。
local.sin_addr.S_un.S_addr=INADDR_ANY;//inet_addr("127.0.0.1");
//初始化Socket
m_Listening=socket(AF_INET,SOCK_STREAM,0);
if(m_Listening == INVALID_SOCKET)
{
puts("创建Winsock实例失败!");
return -1;
}
if(bind(m_Listening,(LPSOCKADDR)&local,sizeof(local)) == SOCKET_ERROR )
{
closesocket(m_Listening);
puts("绑定端口失败!");
return -1;
}
//THREAD m_hListenThread;
//m_hListenThread = ::CreateThread(NULL,0,ListenThread,this,0,&dwThreadID);
if(listen(m_Listening,40) == SOCKET_ERROR)
{
puts("监听端口失败!");
return -1;
}
puts("启动成功");
char szBuf[MAX_PATH];
//初始化
memset(szBuf,0,MAX_PATH);
while(1)
{
SOCKET ConnectSocket;
sockaddr_in ClientAddr;
int nLen = sizeof(sockaddr);
//阻塞直到有客户端连接,不然多浪费CPU资源。
ConnectSocket = accept(m_Listening,(sockaddr*)&ClientAddr,&nLen);
//都到客户端的IP地址。
char *pAddrname = inet_ntoa(ClientAddr.sin_addr);
Receive(ConnectSocket,szBuf,100);
//向客户端发送回应数据
Send(ConnectSocket,szBuf,100);
//界面上显示请求数据。
strcat(szBuf,"\t来自(");
strcat(szBuf,pAddrname);
strcat(szBuf,")");
//closesocket(ConnectSocket);
puts(szBuf);
}
}
ConnectSocket = accept(m_Listening,(sockaddr*)&ClientAddr,&nLen);设断点
感觉是这一步有问题
while ((ConnectSocket == accept(.....))!= INVALID_SOCKET)试试
ConnectSocket = accept(Listening,(sockaddr*)&ClientAddr,&nLen);
一种修改的方法是,创建一个线程来完成服务器与此客户端的通信
阻塞模式,与多个客户端进行通信一般用多线程的方式,类似下面的代码。while(1)
{
AcceptSocket=INVALID_SOCKET;
while(AcceptSocket==INVALID_SOCKET)
{
//AcceptSocket=accept(ListenSocket,NULL,NULL); //addrClient returns client addr info
AcceptSocket=accept(ListenSocket,(sockaddr*)&addrClient,&addrLen); if (AcceptSocket == INVALID_SOCKET)
{
printf("accept failed: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
}
printf("Client connected\n"); DWORD dwThreadId;
HANDLE hThread; //start a thread to manage AcceptSocket
hThread=CreateThread(NULL,NULL,AnswerThread,(LPVOID)AcceptSocket,0,&dwThreadId);
if(hThread==NULL)
{
printf("CreatThread AnswerThread() failed\n");
}
else
{
printf("CreateThread OK\n");
}
}//while(1)
sockaddr_in ClientAddr;
int nLen = sizeof(sockaddr);
ConnectSocket = accept(m_Listening,(sockaddr*)&ClientAddr,&nLen);
把以上 移到 while(1)前面可以完成接受多次数据但是 若先关闭client程序的话 服务器端会崩溃 怎么回事?
accept是相对于你的客户端程序来说,客户端socket是一个,一个port来发送那就是,肯定只有一个accept,又循环到accept这里,肯定阻塞掉了,但是上一个连接仍然在。你没关闭。
只是你没有继续让他接收发送而已。
关闭程序是不是后面没有释放socket