C插座 [英] C sockets

查看:59
本文介绍了C插座的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你好,

i想知道有多个客户连接到同一台服务器

程序以下是正确的代码

#include< sys / types.h>

#include< sys / socket.h>

#include< stdio.h>

#include < netinet / in.h>

#include< signal.h>

#include< unistd.h>


int main()

{

int server_sockfd,client_sockfd;

int server_len,client_len;

struct sockaddr_in server_address;

struct sockaddr_in client_address;


server_sockfd = socket(AF_INET,SOCK_STREAM,0);


server_address.sin_family = AF_INET;

server_address.sin_addr.s_addr = htonl(INADDR_ANY);

server_address.sin_port = htons(9734);

server_len = sizeof(server_address);

bind(server_sockfd,(struct sockaddr *)& server_address,

server_len);


/ *创建一个连接处理队列,忽略子退出详细信息并等待
客户端。 * /


listen(server_sockfd,5);


信号(SIGCHLD,SIG_IGN);


while(1){

char ch;


printf(" server waiting\\\
");


/ *接受连接。 * /


client_len = sizeof(client_address);

client_sockfd = accept(server_sockfd,

(struct sockaddr *)& client_address,& client_len);


/ *用于为此客户创建流程并执行测试以查看

我们是否为父或者孩子。 * /


if(fork()== 0){


/ *如果我们是孩子,我们现在可以阅读/写给客户端

client_sockfd。

五秒延迟仅用于此演示。 * /


读取(client_sockfd,& ch,1);

sleep(5);

ch ++;

写(client_sockfd,& ch,1);

close(client_sockfd);

退出(0);

}


/ *否则,我们必须是父母,我们为这个客户的工作是完成了b
。 * /


else {

close(client_sockfd);

}

}

}


如果是,那么何时使用然后选择呼叫(即FD_SET,FD_CLR,FD_SET)?

如果否则则仅选择有一个服务器套接字程序的东西

pc和许多PC上的其他客户端与服务器进行通信?

我希望与许多客户和一个客户建立通信环境/>
服务器同时服务。

Hello,
i want to know to have multiple clients connects to same server
program does following is correct code
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <netinet/in.h>
#include <signal.h>
#include <unistd.h>

int main()
{
int server_sockfd, client_sockfd;
int server_len, client_len;
struct sockaddr_in server_address;
struct sockaddr_in client_address;

server_sockfd = socket(AF_INET, SOCK_STREAM, 0);

server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = htonl(INADDR_ANY);
server_address.sin_port = htons(9734);
server_len = sizeof(server_address);
bind(server_sockfd, (struct sockaddr *)&server_address,
server_len);

/* Create a connection queue, ignore child exit details and wait for
clients. */

listen(server_sockfd, 5);

signal(SIGCHLD, SIG_IGN);

while(1) {
char ch;

printf("server waiting\n");

/* Accept connection. */

client_len = sizeof(client_address);
client_sockfd = accept(server_sockfd,
(struct sockaddr *)&client_address, &client_len);

/* Fork to create a process for this client and perform a test to see
whether we''re the parent or the child. */

if(fork() == 0) {

/* If we''re the child, we can now read/write to the client on
client_sockfd.
The five second delay is just for this demonstration. */

read(client_sockfd, &ch, 1);
sleep(5);
ch++;
write(client_sockfd, &ch, 1);
close(client_sockfd);
exit(0);
}

/* Otherwise, we must be the parent and our work for this client is
finished. */

else {
close(client_sockfd);
}
}
}

If yes then when to use then select call(i.e. FD_SET,FD_CLR,FD_SET)?
if no then select is only thing to have server socket program on one
pc and other clients on many pcs to have communication with server?
I want to have communication environment with many clients and one
server serving all at same time.

推荐答案

kernel.lover< cr ********** @ gmail.com>写道:
kernel.lover <cr**********@gmail.com> wrote:
我想知道有多个客户端连接到同一台服务器
程序以下是正确的代码
i want to know to have multiple clients connects to same server
program does following is correct code




<代码剪断>


这样你就错了。 C语言确实_not_

对网络操作有任何内置支持,read()

和write()或fork()函数或几乎所有其他函数也没有你是在你的标准C函数的程序中使用
。您使用的唯一函数是标准C函数main(),printf()和

exit()(不计算sizeof(),因为它''不是功能),所有

其余都是系统特定的扩展。所以请把它带到一个新闻 -

小组来处理你正在使用的系统的细节,在你的情况下,
似乎是某种UNIX,所以' 'comp.unix.programmer''

似乎是最合适的。


问候,Jens

-

\ Jens Thoms Toerring ___ Je ******* ****@physik.fu-berlin.de

\ __________________________ http://www.toerring.de


文章< 1d ************** ************@posting.google.com>,

kernel.lover< cr ********** @ gmail.com>写道:

:我想知道有多个客户连接到同一台服务器

:程序以下是正确的代码


套接字不是C标准的一部分,因此大多数人会将b $ b引用到comp.unix.programming或类似的新闻组。


:if (fork()== 0){


:}


:else {

:close(client_sockfd) );

:}


该代码不正确:一段时间后它将停止接受

连接。这是因为父母从来没有等待()

或waitpid()或wait3()来收集死去的孩子的状态,

所以死去的孩子将继续徘徊并堆积起来,直到

某些资源耗尽。

:如果是,那么何时使用然后选择呼叫(即FD_SET,FD_CLR,FD_SET)?

:如果没有那么select只是将服务器套接字程序放在一个上的东西

:pc和许多pc上的其他客户端与服务器进行通信?

:我希望与许多客户建立通信环境,并且一个服务器同时提供服务。


有多个正确的;当你想要执行异步动作时,
select()非常有用,或者想要给出等待输入的时间限制。


你想要select()的例子是一个案例

你有一个例程,你正在接收来自
的数据
a管道,但也与用户沟通:你不知道
知道两个输入源中的哪一个将首先准备好,

so你使用select()告诉你第一个就是

准备好了。


当你fork()一个新进程来处理每个客户端时,那么你需要

要注意 - 逻辑上说,父的完整副本

进程及其所有变量都是创建的,所以 - 逻辑上讲<服务N个客户端的
至少需要(N + 1)次主进程占用的内存量

。大多数现代unix系统通过使用诸如copy on write等技巧来优化实际内存使用量。 (

将内存划分为页面并共享页面的副本,直到一个

进程写入页面,此时该进程被给予

页面的非共享副本。)这是具体的内容 -

具体,但可能取决于您当前的内核设置和

当前资源限制:在某些系统中,操作系统会想要保留足够的实际内存以制作父进程的完整副本,即使它没有'b $ b'知道父进程需要内存。

理论上说如果在fork的时候保留完整的内存,那么如果fork成功了你知道你可以写入所有现有变量的
,而在那些执行

" copy on write"并且不要提前保留所有内存,你这样做是否存在内存不足和崩溃过程的风险

通过,即使你认为你是只写一个位置

即已知存在[因为写入触发了副本和

新页面没有足够的空间。]


如果你没有fork()而是在一个

流程中处理所有内容,然后一个流程必须跟踪所有流程的所有状态

;保持一切顺利可能

使代码复杂化。此外,如果您只使用一个

流程,那么除非您可以利用线程然后

一个进程必须完成所有的计算工作 - 并且

在进行计算工作时,它很忙并且不能

代表不同的套接字进行计算工作,

也不能在忙碌计算时进行套接字I / O.

响应时间可能变得不可接受,而

fork()案例可能能够在一个不同的CPU上运行分叉进程(如果你有一台多CPU机器。)


另外,如果你采取在一个过程中完成所有事情的方法,那么

如果你足够忙,你将耗尽可用的插座

描述符。如果你为每个插槽使用FILE * I / O,那么你可以在100或255个活动套接字中耗尽
。 100曾经是

普通的实施限制; 255出现了通常使用

单个字符来保存底层描述符号。找出你可以打开多少文件的方式是询问

sysconf(_SC_OPEN_MAX) - 注意sysconf()是一个POSIX例程,

不是C库例程。

-

''ignorandus(拉丁语):值得不知道'''

- 自我指涉日志
In article <1d**************************@posting.google.com >,
kernel.lover <cr**********@gmail.com> wrote:
: i want to know to have multiple clients connects to same server
:program does following is correct code

Sockets aren''t part of the C standard, so most people would
refer you to comp.unix.programming or a similar newsgroup.

: if(fork() == 0) {

: }

: else {
: close(client_sockfd);
: }

That code is not correct: after a time it will stop accepting
connections. That''s because the parent never does a wait()
or waitpid() or wait3() to collect the status of the dead children,
so the dead children are going to linger on and pile up until
some resource is exhausted.
:If yes then when to use then select call(i.e. FD_SET,FD_CLR,FD_SET)?
:if no then select is only thing to have server socket program on one
:pc and other clients on many pcs to have communication with server?
: I want to have communication environment with many clients and one
:server serving all at same time.

There is more than one "correct" way.

select() is useful when you want to perform asynchronous action,
or want to put a time limit on how long you will wait for input.

An example of where you would want select() is in a case
where you have a routine which you are receiving data from
a pipe but are also in communication with the user: you don''t
know which of the two input sources is going to be ready first,
so you use select() to tell you as soon as the first of them is
ready.

When you fork() a new process to handle each client, then you need to
be aware that -logically- speaking, an entire copy of the parent
process and all of its variables is created, so -logically- speaking
serving N clients requires at least (N+1) times the amount of memory
that the master process takes. Most modern unix systems optimize the
actual memory usage by using tricks such as "copy on write" (which
divides the memory into "pages" and shares copies of the page until one
process writes to the page, at which point that process is given an
unshared copy of the page.) That''s something that is implimentation-
specific, though, and may depend upon your current kernel settings and
current resource limits: in some systems, the OS will want to reserve
enough real memory to make a complete copy of the parent process, even
though it doesn''t know that the parent process will need the memory.
The theory there is that if the complete memory is reserved at the time
of the fork, then if the fork successed you know that you will be able
to write to all the existing variables, whereas in systems which do
"copy on write" and do not reserve all the memory ahead of time, you
run the risk of running out of memory and crashing the process part way
through, even though you thought you were just writing to a location
that is "known" to exist [because the write triggered the copy and
there wasn''t enough room for the new page.]

If you do not fork() and instead handle everything in one
process, then that one process has to keep track of all the state
for all of the processes; keeping everything straight could
complicate the code a fair bit. Also, if you use only a single
process then unless you can take advantage of "threads" then
that one process has to do all the computation work -- and
while it is doing computation work, it is busy and cannot be
doing computation work on behalf of a different socket,
nor can it be doing socket I/O while it is busy computing.
The response times might become unacceptable, whereas the
fork() case might be able to run the forked process on a
different CPU (if you have a multi-cpu machine.)

Also, if you take the approach of doing everything in one process, then
if you get busy enough, you are going to run out of available socket
descriptors. If you are using FILE* I/O for each socket then you could
run out in as little as 100 or 255 active sockets. 100 used to be a
common implimentation limit; 255 arises out of the common use of a
single character to hold the underlying descriptor number. The way of
finding out how many files you can open is to ask to
sysconf(_SC_OPEN_MAX) -- note that sysconf() is a POSIX routine,
not a C library routine.
--
''ignorandus (Latin): "deserving not to be known"''
-- Journal of Self-Referentialism


Walter Roberson< ro ****** @ ibd.nrc-cnrc.gc.ca>写道:
Walter Roberson <ro******@ibd.nrc-cnrc.gc.ca> wrote:
在文章< 1d ************************** @ posting.google.com>中,
kernel.lover< cr ********** @ gmail.com>写道:
:我想知道有多个客户端连接到同一台服务器
:程序执行以下是正确的代码
套接字不是C标准的一部分,所以大多数人会
向您推荐comp.unix.programming或类似的新闻组。


这是有充分理由的,因为有人

将负责纠正回复中的任何错误。

所以,如果你不能回答这里至少设置

后续适当的。


:if(fork()== 0 ){
:}
:else {
:close(client_sockfd);
:}
该代码不正确:一段时间后它将停止接受
连接。这是因为父母从来没有等待()
或waitpid()或wait3()来收集死去的孩子的状态,所以死去的孩子会徘徊并堆积起来直到
某些资源耗尽。
In article <1d**************************@posting.google.com >,
kernel.lover <cr**********@gmail.com> wrote:
: i want to know to have multiple clients connects to same server
:program does following is correct code Sockets aren''t part of the C standard, so most people would
refer you to comp.unix.programming or a similar newsgroup.
And that for a good reason since there are the people that
will take care of correcting any mistakes made in replies.
So, if you can''t refrain from answering here at least set
follow-ups appropriately.

: if(fork() == 0) { : } : else {
: close(client_sockfd);
: } That code is not correct: after a time it will stop accepting
connections. That''s because the parent never does a wait()
or waitpid() or wait3() to collect the status of the dead children,
so the dead children are going to linger on and pile up until
some resource is exhausted.




并且只是为了避免发出信号


信号(SIGCHLD,SIG_IGN);

在您剪切的fork()之前的
- 该设置阻止了

创建僵尸,至少假设OP正在使用UNIX。请

我需要多说赞成保留适当的

新闻组?

问候,Jens

-

\ Jens Thoms Toerring ___ Je *** ********@physik.fu-berlin.de

\ __________________________ http://www.toerring.de


这篇关于C插座的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆