user-0 提问: socket 服务器给指定的客户端发消息该怎么处理（tcp）（c语言）

回复:
user: user-1
content: 定义好客户类，用链表保存连接的客户，转发的时候找到对应的客户通过socket将消息发出去即可。

user: user-2
content: 楼主需要自定义一套协议。 这个协议的具体形式就是 数据包的数据结构的定义。  就类似于TCP/IP 规定的那样，有个包头，包头的哪些字节都有自己代表的特定含义。

user: user-0
content: 引用 17 楼 zhao4zhong1 的回复:talk is cheap, show me your codes. 第35行clientfd数组里是i-1的时候后建立连接的客户端2可以向客户端1发送消息，但当客户端1向客户端2发送消息时服务器会显示send: Socket operation on non-socket，此时clientfd[i-1]恒等于是客户端2的描述符，所以我想因该是recv（）函数那块处理的不好？？？

user: user-0
content: 引用 17 楼 zhao4zhong1 的回复:talk is cheap, show me your codes. 第35行clientfd数组里应该是j不是i-1。。。sorry

user: user-0
content: 引用 17 楼 zhao4zhong1 的回复:talk is cheap, show me your codes. 一大波codes来袭！！！！             。            。            。            。 //用int数组来保存与服务器连接成功的socket  if((clientfd[i] = accept(sockfd,(struct sockaddr*)&their_addr,&sin_size)) == -1)       {        perror("accept");        exit(1);       }else       {       i++;         }   printf("accept from:%d\n",inet_ntoa(their_addr.sin_addr));      send(clientfd[i-1],WELCOME,strlen(WELCOME),0);//发送问候信息      buf = (char *)malloc(255);  //显示accept（）返回的描述符     printf("clientfh：%d",clientfd[i-1]);       ppid = fork();//创建子进程      if(ppid == 0)      {                pid = fork();  //创建子进程           while(1)        {          if(pid > 0)          {  	    int j;          for( j=0;j<i;j++){            if((recvbytes = recv(clientfd[i-1],buf,255,0)) <= 0)            {              perror("recv1");              close(clientfd[i-1]);              raise(SIGKILL);//raise（）向正在执行的程序发送信号，               exit(1);            }else{break;}            }           //显示发送到缓冲区的消息和那个socket接受的            printf(" %s,%d\n",buf,clientfd[j]);                     //要向那个客户端发送数据在buf的第一个字符 	   switch(buf[0])            {              case '0':choice=0;break;              case '1':choice=1;break;              case '2':choice=2;break;              case '3':choice=3;break;              case '4':choice=4;break; 		default:break;            }                                                   //在服务器显示内容             printf(" %s\n",buf); //向指定客户端发送消息     if(send(clientfd[choice],buf,strlen(buf),0) == -1)              {                perror("send");              }           }  //一开始send（）在下面的子进程里，可是子进程里的代码却执行不了于是我就放到上面去勒，准备再开改一下          else if(pid == 0)//子进程发送消息          {          if(send(clientfd[choice],buf,strlen(buf),0) == -1)              {                perror("send");              }            。            。            。            。

user: user-3
content: talk is cheap, show me your codes.

user: user-3
content: printf("socket1==%08x\n",(int)socket1);

user: user-0
content: 引用 14 楼 zhao4zhong1 的回复:[quote=引用 13 楼 wocawuliao 的回复:] [quote=引用 11 楼 u011274968 的回复:] 1.客户端连接服务器时首先分配各客户端的ID。 2.向服务器传送信息“客户端1向客户端2发送信息” 3.服务器在自己所拥有的客户端目录中查找客户端2的ID并进行信息传送。 第一个：我是用一个数组来保存accept（）返回的套接字，这样可不可以？有没有跟好的办法？[/quote] 我就是“用一个数组来保存accept（）返回的套接字”的。[/quote] 客户端1与服务端建立连接后再让客户端2与服务端建立连接，，， recv（）的第一个参数该如何设置那，？？？ 我是用一个循环，把所有客户端套接字带到recv（）中都试一遍，可是reck（）的第一个参数一直都是客户端1的描述符？？？

user: user-3
content: 引用 13 楼 wocawuliao 的回复:[quote=引用 11 楼 u011274968 的回复:] 1.客户端连接服务器时首先分配各客户端的ID。 2.向服务器传送信息“客户端1向客户端2发送信息” 3.服务器在自己所拥有的客户端目录中查找客户端2的ID并进行信息传送。 第一个：我是用一个数组来保存accept（）返回的套接字，这样可不可以？有没有跟好的办法？[/quote] 我就是“用一个数组来保存accept（）返回的套接字”的。

user: user-0
content: 引用 11 楼 u011274968 的回复:1.客户端连接服务器时首先分配各客户端的ID。 2.向服务器传送信息“客户端1向客户端2发送信息” 3.服务器在自己所拥有的客户端目录中查找客户端2的ID并进行信息传送。 第一个：我是用一个数组来保存accept（）返回的套接字，这样可不可以？有没有跟好的办法？

user: user-0
content: 引用 10 楼 cjfdqchwh 的回复:楼主需要自定义一套协议。 这个协议的具体形式就是 数据包的数据结构的定义。  就类似于TCP/IP 规定的那样，有个包头，包头的哪些字节都有自己代表的特定含义。 accept()建立连接返回新的套接字描述符后，就没有他啥事勒。。。后续的接受消息由recv（）函数的第一个参数指定接受消息的链接？？？这样理解对不对？？？

user: user-4
content: 1.客户端连接服务器时首先分配各客户端的ID。 2.向服务器传送信息“客户端1向客户端2发送信息” 3.服务器在自己所拥有的客户端目录中查找客户端2的ID并进行信息传送。

user: user-5
content: 引用 楼主 wocawuliao 的回复:多个客户端之间进行通讯，通过服务器转发的形式，现在客户端1请求向客户端2发送消息，先把消息发送到服务器，服务器怎么才能把消息转发到客户端2而不是转发给客户端3或者他自己。    请高手指教下该如何处理！ 客户端1需要在发送的消息头中加上一个标志位，告诉服务器需要发送给那个客户端！ 然后服务器再达到转发的功能的！  这个彼此的协议协商好就好了！

user: user-6
content: 如： 中转服务器有一个map表，客户名+socket 客户1要发给客户2 客户1发送报文里面sender字段就是客户2，到服务器找到客户2对应的socket，直接发出去....

user: user-0
content: 引用 6 楼 wocawuliao 的回复:[quote=引用 5 楼 max_min_ 的回复:] [quote=引用 4 楼 wocawuliao 的回复:] [quote=引用 2 楼 max_min_ 的回复:] [quote=引用 楼主 wocawuliao 的回复:] 多个客户端之间进行通讯，通过服务器转发的形式，现在客户端1请求向客户端2发送消息，先把消息发送到服务器，服务器怎么才能把消息转发到客户端2而不是转发给客户端3或者他自己。    请高手指教下该如何处理！ 客户端1需要在发送的消息头中加上一个标志位，告诉服务器需要发送给那个客户端！ 然后服务器再达到转发的功能的！  这个彼此的协议协商好就好了！[/quote] 有两个疑问： 1.accept（）函数的第二个参数的结构中包含着客户端的ip和端口信息？ 2.accept（）函数调用成功后返回的新的套接字地址结构中ip和端口如何设置的？[/quote]  1 是的！ 2 socket和连接成功的客户端通信！不需要设置什么ip和端口！[/quote] 版主就是不一样这速度！！！！！谢谢了[/quote] 在麻烦一下版主！！！ 我有这样的一个想法：  1.在服务器端用一个int型的clientfd[]数组来接收accept（）函数建立连接时新建的socket描述符  2.假如有clientfd[0]和clientfd[1]两个客户端建立了连接  3.让clientfd[0]和clientfd[1]分别调用一次fork（）函数父进程接受，子进程发送  4.clientfd[0]子进程发送时将send（）函数的第一个参数设置成clientfd[1]  这样行的通吗？有什么错误？

user: user-7
content: 引用 7 楼 wocawuliao 的回复:[quote=引用 3 楼 a345485527 的回复:] 首先服务器要保存与每个客户端连接的socket， 其次 客户端1告诉服务器：我要把这个消息传个客户端2，服务器就从它保存的socket里找到客户端2对应的socket， 最后，用找到的这个客户2的socket把1的信息发给2就好了 找到的这个客户2的socket把1的信息发给2是通过设置send（）函数的第一个参数为2的socket描述符吗？这样： send（seocketfd2，。。。。，。。。）；[/quote]  是的 send函数第一个参数就是socket，这个socketfd2就是专门负责与客户2通信的socket了，也就是说是客户2专属的，你在这个套接字上send，就只能发到客户端2上面去，也不需要设置IP,端口什么的 看来lz是没有太理解明白，我摘一段APUE中的原文： 对于面向连接的套接字，目标地址是忽略的，因为目标地址蕴涵在连接中

user: user-0
content: 引用 3 楼 a345485527 的回复:首先服务器要保存与每个客户端连接的socket， 其次 客户端1告诉服务器：我要把这个消息传个客户端2，服务器就从它保存的socket里找到客户端2对应的socket， 最后，用找到的这个客户2的socket把1的信息发给2就好了 找到的这个客户2的socket把1的信息发给2是通过设置send（）函数的第一个参数为2的socket描述符吗？这样： send（seocketfd2，。。。。，。。。）；

user: user-0
content: 引用 5 楼 max_min_ 的回复:[quote=引用 4 楼 wocawuliao 的回复:] [quote=引用 2 楼 max_min_ 的回复:] [quote=引用 楼主 wocawuliao 的回复:] 多个客户端之间进行通讯，通过服务器转发的形式，现在客户端1请求向客户端2发送消息，先把消息发送到服务器，服务器怎么才能把消息转发到客户端2而不是转发给客户端3或者他自己。    请高手指教下该如何处理！ 客户端1需要在发送的消息头中加上一个标志位，告诉服务器需要发送给那个客户端！ 然后服务器再达到转发的功能的！  这个彼此的协议协商好就好了！[/quote] 有两个疑问： 1.accept（）函数的第二个参数的结构中包含着客户端的ip和端口信息？ 2.accept（）函数调用成功后返回的新的套接字地址结构中ip和端口如何设置的？[/quote]  1 是的！ 2 socket和连接成功的客户端通信！不需要设置什么ip和端口！[/quote] 版主就是不一样这速度！！！！！谢谢了

user: user-5
content: 引用 4 楼 wocawuliao 的回复:[quote=引用 2 楼 max_min_ 的回复:] [quote=引用 楼主 wocawuliao 的回复:] 多个客户端之间进行通讯，通过服务器转发的形式，现在客户端1请求向客户端2发送消息，先把消息发送到服务器，服务器怎么才能把消息转发到客户端2而不是转发给客户端3或者他自己。    请高手指教下该如何处理！ 客户端1需要在发送的消息头中加上一个标志位，告诉服务器需要发送给那个客户端！ 然后服务器再达到转发的功能的！  这个彼此的协议协商好就好了！[/quote] 有两个疑问： 1.accept（）函数的第二个参数的结构中包含着客户端的ip和端口信息？ 2.accept（）函数调用成功后返回的新的套接字地址结构中ip和端口如何设置的？[/quote]  1 是的！ 2 socket和连接成功的客户端通信！不需要设置什么ip和端口！

user: user-0
content: 引用 2 楼 max_min_ 的回复:[quote=引用 楼主 wocawuliao 的回复:] 多个客户端之间进行通讯，通过服务器转发的形式，现在客户端1请求向客户端2发送消息，先把消息发送到服务器，服务器怎么才能把消息转发到客户端2而不是转发给客户端3或者他自己。    请高手指教下该如何处理！ 客户端1需要在发送的消息头中加上一个标志位，告诉服务器需要发送给那个客户端！ 然后服务器再达到转发的功能的！  这个彼此的协议协商好就好了！[/quote] 有两个疑问： 1.accept（）函数的第二个参数的结构中包含着客户端的ip和端口信息？ 2.accept（）函数调用成功后返回的新的套接字地址结构中ip和端口如何设置的？