关于socket问题

zll_lover 2010-07-16 06:16:36
我想问一下一个服务器程序建立socket连接
然后accept请求
这是newsocket=accept。。。
我的问题是在我没有close(newsocket)之前
如果有客户端连接,服务器会accept新的socket吗?
如果不会该如何解决服务器同时与多个客户端通信呢(只有派生子进程了吗)
客户端close(newsocket)与服务器端close(newsocket)效果是否一样呢?
最后一个问题,select可以同时监听多个socket,如果服务器不会同时接受多个客户端通信那它的意义何在呢?
谢谢我是新手
...全文
361 37 打赏 收藏 转发到动态 举报
写回复
用AI写文章
37 条回复
切换为时间正序
请发表友善的回复…
发表回复
fu15229018 2011-11-07
  • 打赏
  • 举报
回复
zhangweiit

非常牛B,佩服!从你这学到不少东西。
sallan 2010-07-18
  • 打赏
  • 举报
回复
mark
184270428 2010-07-18
  • 打赏
  • 举报
回复
想看完整代码,到我资源里下吧。
是一个DLL源码。
184270428 2010-07-18
  • 打赏
  • 举报
回复
贴段代码给你:
BOOL WINAPI OpenSocketService(LONG port,LONG link_count,LPCTSTR err_text)
{
__try
{
if(!link_count)
{
err_text = (LPCTSTR)"监听数必须大于零";
return FALSE;
}
frompbinfo.link_count = link_count;
frompbinfo.port = port;
WSADATA wsd;
SOCKADDR_IN addr;
HOSTENT * host;
CHAR name[128];


if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
{
sprintf((char *)err_text, "载入通信组件失败,请检查网络组件是否正常!,错误号:%d",WSAGetLastError());
return FALSE;
}
socket_listen = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(socket_listen == INVALID_SOCKET)
{
sprintf((char *)err_text, "创建套节字失败!,错误号:%d",WSAGetLastError());
WSACleanup();
return FALSE;
}
if(gethostname(name,sizeof(name)) == -1)
{
sprintf((char *)err_text, "获取电脑名失败!");
WSACleanup();
return FALSE;
}


host = gethostbyname(name);
addr.sin_family = AF_INET;
addr.sin_addr =*(IN_ADDR *)host->h_addr;
//addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port =htons(port & MAXWORD);
if(bind(socket_listen,(SOCKADDR *)&addr,sizeof(addr)) == SOCKET_ERROR)
{
closesocket(socket_listen);
sprintf((char *)err_text, "绑定套节字失败!错误号:%d",WSAGetLastError());
WSACleanup();
return FALSE;
}
if(listen(socket_listen,link_count) == SOCKET_ERROR)
{
closesocket(socket_listen);
sprintf((char *)err_text, "打开监听失败!");
WSACleanup();
return FALSE;
}

server_thread = CreateThread(
NULL,
0,
ServerListenThread,
NULL,
0,
NULL
);
if(!server_thread)
{
closesocket(socket_listen);
sprintf((char *)err_text, "打开通讯服务失败!");
WSACleanup();
return FALSE;
}

return TRUE;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
sprintf((char *)err_text,"未知的错误,错误号:%d",GetLastError());
return FALSE;
}
}

DWORD WINAPI ServerListenThread(LPVOID lpParam)//监听线程
{
SOCKADDR_STORAGE saAccept;
SOCKET ns;
CONNECTION_OBJ *connobj;
//int timeout=3000;
int acceptlen = sizeof(SOCKADDR_STORAGE);
BEGIN:
__try
{

while (TRUE)
{
Sleep(0);
ns = accept(socket_listen, (SOCKADDR *)&saAccept, &acceptlen);
if (ns == INVALID_SOCKET)
{
continue;
}
//setsockopt(ns,SOL_SOCKET, SO_SNDTIMEO, ( char * )&timeout, sizeof(int) );
//setsockopt(ns,SOL_SOCKET, SO_RCVTIMEO, ( char * )&timeout, sizeof(int) );
connobj=CreateConnectionObj(ns,(SOCKADDR *)&saAccept,acceptlen);
connobj->hthread=CreateThread(NULL, 0, ReceiveThread, (LPVOID)connobj, 0, NULL);
InsertConnectionobj(connobj);
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
goto BEGIN;
}
return 0;
}
aizibion 2010-07-17
  • 打赏
  • 举报
回复
[Quote=引用 26 楼 zhangweiit 的回复:]
引用 24 楼 aizibion 的回复:

即使close(newsocket),服务端一样会接受新连接哈,执行accept动作的是listen_socket,望悉


你没有认真看我的19楼的回复,我已经声明我上面说法的失误了
我已经声明,我看错了,我意思指的是close 服务端的socket
close一个客户端socket当然不会影响新的连接
[/Quote]

兄弟,我想还是说清楚点的好,不是我钻牛角尖,因为从进程的层面或是业务层面,newsocket,listen_socket都是服务端的socket,另外,不论新手老手,如果说到服务端、客户端,都不太可能把他们认为是一个进程或是一个业务。。。
望谅
zhangweiit 2010-07-17
  • 打赏
  • 举报
回复
楼主,这个贴盖了28楼可以结了,
有问题可以开新贴大家再回答
zhangweiit 2010-07-17
  • 打赏
  • 举报
回复
回复不能修改是挺麻烦的,
这样,一旦写错了,就误导很多人了
zhangweiit 2010-07-17
  • 打赏
  • 举报
回复
[Quote=引用 24 楼 aizibion 的回复:]

即使close(newsocket),服务端一样会接受新连接哈,执行accept动作的是listen_socket,望悉
[/Quote]

你没有认真看我的19楼的回复,我已经声明我上面说法的失误了
我已经声明,我看错了,我意思指的是close 服务端的socket
close一个客户端socket当然不会影响新的连接
清雨小竹 2010-07-17
  • 打赏
  • 举报
回复
你可以采用多线程或者异步通信模式
aizibion 2010-07-17
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 zhangweiit 的回复:]
Q:"我的问题是在我没有close(newsocket)之前
如果有客户端连接,服务器会accept新的socket吗?"
A:
如果没有close,正常情况下,会不断accept新连接


Q:如何解决服务器同时与多个客户端通信呢?(只有派生子进程了吗)?
A:一个服务端可以同时保持与n个客户端socket的连接,这与子进程无关
当然,你可以自己创建一个线程去分别管理每个socket……
[/Quote]

即使close(newsocket),服务端一样会接受新连接哈,执行accept动作的是listen_socket,望悉
zhangweiit 2010-07-17
  • 打赏
  • 举报
回复
论坛,之所以为论坛,就是可以大家发表各自言论
所以,你不用这么客气啦,呵呵
zhangweiit 2010-07-17
  • 打赏
  • 举报
回复
论坛上的问题,主要是把那个关键点拨开就好的
就像上面的问题,你说的我是非常认同的
当然我在工作中也是这样做的
如果我是错误的方法,我早就失业了

但是,在这里说话,只是简单的提问与回答
真的可以不用去钻牛角尖的

如果是楼主QQ跟我聊,我会聊多一些
毕竟看贴子,是看一下过的
主要意思表达出来就过了
当然也承认,有时候讲的不会完全准确,甚至是错误的,因为我们的水平本来就有限
还有就是各人表达与理解的问题了
zhangweiit 2010-07-17
  • 打赏
  • 举报
回复
[Quote=引用 29 楼 aizibion 的回复:]

引用 26 楼 zhangweiit 的回复:
引用 24 楼 aizibion 的回复:

即使close(newsocket),服务端一样会接受新连接哈,执行accept动作的是listen_socket,望悉


你没有认真看我的19楼的回复,我已经声明我上面说法的失误了
我已经声明,我看错了,我意思指的是close 服务端的socket
close一个客户端socket当……
[/Quote]

哈,不用望谅,不需要谅啊,讲这么客气
没错,你说的是对的

只是,平常在论坛上讲话,有时候,都是大概意思的,不会去百分百精确的
而且,有的时候,也是基于楼主的理解方式来说的
不论怎样,只要他理解了就好
至于深入的理解,相信楼主自然会去读书,看资料的,这些东西本来就不是论坛上可以完全学会的
mymtom 2010-07-16
  • 打赏
  • 举报
回复
《Unix网络编程》
ctj笨笨 2010-07-16
  • 打赏
  • 举报
回复
na2650945 2010-07-16
  • 打赏
  • 举报
回复
学到很多呀。
zhangweiit 2010-07-16
  • 打赏
  • 举报
回复
我补充一下,我在3楼的贴子有
我说的close socket,是指关闭服务端socket的

关闭一个客户端的socket当然不会影响接收其它服务端

不过,谢谢17楼的提醒,以免我误导他人
phpjspasp 2010-07-16
  • 打赏
  • 举报
回复
强烈推荐你看一看 unix网络编程,这本书讲得太清楚了。
cattycat 2010-07-16
  • 打赏
  • 举报
回复
网络编程看来你基础还不扎实啊,好好看看tcp/ip详解,windows网络编程或unix网络编程的书。

accept能持续监听新的客户端的连接,与你关闭前一个socket无关。一般最简单的就是accept一个socket后创建线程处理该socket的收发数据请求。另外accept是阻塞的。
select监听多个socket是为了提升性能的,就是为了克服accept这种阻塞方式,如果你accept这种方式能满足要求,就可以不用select.
zhangweiit 2010-07-16
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 hairetz 的回复:]

你是说recv吗?这个时候会阻塞的,或者可以用select+阻塞模型,或者建一个子线程并发都可以。
[/Quote]

recv是会阻塞啊,不过,他说的是意思大概是,客户端的阻塞,是否会影响服务端,导致不能接收新的客户端
加载更多回复(15)

64,648

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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