socket,导致“videlord”网友说的情况:对于tcp
socket,send与recv不是对等的,recv时只要缓冲有数据就会收上来。简单说就是你send
4次,比如分别为10
10
10
10字节,对端可以一次recv到这40字节数据,也可以recv
40次、每次1字节。
解决办法有两种:
1.
改用udp
socket,send/recv自然对等了
2.
继续用tcp
socket,自己进行数据分段:比如自行约定在数据前约定4个字节用于描述数据长度,这样发送时,send
4+33字节,send
4+35字节;接收时,先获取描述长度的4字节获得长度,再按照长度
接收数据
(可能需要多次recv凑齐指定长度)。
假设服务器的守护进程为D,D维护着一张广播链表。假设链表元素为struct BEntry{
pid_t pid //服务器子进程id
mqd_t mqd//消息队列描述符或者其他IPC手段也可以
}
每次有客户端连上来,做fork的时候就把IPC手段建立好,不管用管道,或者消息,或者共享内存都大同小异,设客户端连上来fork产生的服务器子进程为Subn n为下标。
然后如果要广播消息,就让Subn通知D(可以用广播链表里的IPC手段,也可以另建),然后由D广播消息给各个Subm, Subx,这些Sub进程再发给客户端,这样可以同时广播,效率比较高。
只是做这些动作的话不需要多线程找了下以前写的 改成了你说的10次发送client.c:#include<stdio.h>#include<stdlib.h>#include<string.h>#include<errno.h>#include<sys/types.h>#include<sys/socket.h>#include<netinet/in.h>int main(int argc,char **argv){ char wbuf[] = "hello server" char rbuf[128] int i int sock struct sockaddr_in server = {0} struct timeval timeo timeo.tv_sec = 0 timeo.tv_usec = 1000 * 1000 // socklen_t len = sizeof(timeo) if( argc != 2){ printf("usage: ./client <ipaddress>\n") return -1 } sock = socket(AF_INET, SOCK_STREAM, 0) if(sock <0) { perror("Create TCP Socket") return -1 } setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, &timeo, len) server.sin_family = AF_INET server.sin_port = htons(30000) inet_pton(AF_INET, argv[1], &(server.sin_addr)) int res = connect(sock, (struct sockaddr*)&server, sizeof(server)) if (res <0) { if(res == EINPROGRESS) perror("connecting stream socket time out:") else perror("connecting stream socket error:") close(sock) return -1 } else { printf("Connect Server@%s\n",argv[1]) for(i=0i<10i++) { int wsize = send(sock,wbuf,sizeof(wbuf),0) if(wsize<=0) { perror("write error:") close(sock) return -1 } printf("1111111i=%d\n",i) while(1) { int rsize=recv(sock,rbuf,sizeof(rbuf),0) if(rsize>0) { rbuf[rsize]='\0' printf("recv msg from server: %s\n",rbuf) break } if(rsize<0) { close(sock) perror("read error:") return -1 } } } close(sock) return 0 }}server.c:#include<stdio.h>#include<stdlib.h>#include<string.h>#include<errno.h>#include<sys/types.h>#include<sys/socket.h>#include<netinet/in.h>int main(int argc, char** argv){intlistenfd, connfd struct sockaddr_in servaddr = {0} charrbuf[128] charwbuf[] = "hello client" int n if( (listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1 ){ perror("Create TCP Socket") return -1 }servaddr.sin_family = AF_INET servaddr.sin_addr.s_addr = htonl(INADDR_ANY) servaddr.sin_port = htons(30000) if( bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) == -1){ perror("bind socket error:") return -1 }if( listen(listenfd, 10) == -1){ perror("listen socket error:") return -1 }printf("======waiting for client's request======\n") while(1){ if( (connfd = accept(listenfd, (struct sockaddr*)NULL, NULL)) == -1) {perror("accept socket error:") continue } while(1) { n = recv(connfd, rbuf, sizeof(rbuf), 0) if(n>0) { rbuf[n] = '\0' printf("recvmsg from client: %s\n", rbuf) n = send(connfd, wbuf, sizeof(wbuf),0) if(n<=0) { perror("sned error:") close(connfd) break } } else if(n <0) { perror("recv error:") close(connfd) break } } close(connfd) }close(listenfd) return 0}运行的时候 client ./client 你的serverip端口我用的30000 写死在程序里了欢迎分享,转载请注明来源:内存溢出
评论列表(0条)