📄 socket.c
字号:
continue; } fprintf(stderr,"prsocket_test: ERROR - PR_Bind failed\n"); perror("PR_Bind"); failed_already=1; goto exit; } if (PR_Listen(sockfd, 32) < 0) { fprintf(stderr,"prsocket_test: ERROR - PR_Listen failed\n"); failed_already=1; goto exit; } if (PR_GetSockName(sockfd, &netaddr) < 0) { fprintf(stderr,"prsocket_test: ERROR - PR_GetSockName failed\n"); failed_already=1; goto exit; } DPRINTF(("TCP_Server: PR_BIND netaddr.inet.ip = 0x%lx, netaddr.inet.port = %d\n", netaddr.inet.ip, netaddr.inet.port)); if (PR_SetNetAddr(PR_IpAddrLoopback, client_domain, PR_ntohs(PR_NetAddrInetPort(&netaddr)), &tcp_server_addr) == PR_FAILURE) { fprintf(stderr,"prsocket_test: PR_SetNetAddr failed\n"); goto exit; } if ((client_domain == PR_AF_INET6) && (server_domain == PR_AF_INET)) PR_ConvertIPv4AddrToIPv6(PR_htonl(INADDR_LOOPBACK), &tcp_server_addr.ipv6.ip); /* * Wake up parent thread because server address is bound and made * available in the global variable 'tcp_server_addr' */ PR_PostSem(sp->addr_sem); for (i = 0; i < (num_tcp_clients * num_tcp_connections_per_client); i++) { /* test both null and non-null 'addr' argument to PR_Accept */ PRNetAddr *addrp = (i%2 ? &netaddr: NULL); DPRINTF(("TCP_Server: Accepting connection\n")); if ((newsockfd = PR_Accept(sockfd, addrp, PR_INTERVAL_NO_TIMEOUT)) == NULL) { fprintf(stderr,"prsocket_test: ERROR - PR_Accept failed\n"); goto exit; } DPRINTF(("TCP_Server: Accepted connection\n")); scp = PR_NEW(Serve_Client_Param); if (scp == NULL) { fprintf(stderr,"prsocket_test: PR_NEW failed\n"); goto exit; } /* * Start a Serve_Client thread for each incoming connection */ scp->sockfd = newsockfd; scp->datalen = sp->datalen; t = create_new_thread(PR_USER_THREAD, Serve_Client, (void *)scp, PR_PRIORITY_NORMAL, PR_LOCAL_THREAD, PR_UNJOINABLE_THREAD, 0, i); if (t == NULL) { fprintf(stderr,"prsocket_test: PR_CreateThread failed\n"); failed_already=1; goto exit; } DPRINTF(("TCP_Server: Created Serve_Client = 0x%lx\n", t)); }exit: if (sockfd) { PR_Close(sockfd); } /* * Decrement exit_counter and notify parent thread */ PR_EnterMonitor(sp->exit_mon); --(*sp->exit_counter); PR_Notify(sp->exit_mon); PR_ExitMonitor(sp->exit_mon); DPRINTF(("TCP_Server [0x%lx] exiting\n", PR_GetCurrentThread()));}/* * UDP Server * Server Thread * Bind an address to a socket, read data from clients and send data * back to clients */static void PR_CALLBACKUDP_Server(void *arg){ Server_Param *sp = (Server_Param *) arg; PRFileDesc *sockfd; buffer *in_buf; PRNetAddr netaddr; PRInt32 bytes, i, rv = 0; bytes = sp->datalen; /* * Create a udp socket */ if ((sockfd = PR_OpenUDPSocket(server_domain)) == NULL) { fprintf(stderr,"prsocket_test: PR_NewUDPSocket failed\n"); failed_already=1; return; } memset(&netaddr, 0 , sizeof(netaddr)); if (PR_SetNetAddr(PR_IpAddrAny, server_domain, UDP_SERVER_PORT, &netaddr) == PR_FAILURE) { fprintf(stderr,"prsocket_test: PR_SetNetAddr failed\n"); failed_already=1; return; } /* * try a few times to bind server's address, if addresses are in * use */ i = 0; while (PR_Bind(sockfd, &netaddr) < 0) { if (PR_GetError() == PR_ADDRESS_IN_USE_ERROR) { netaddr.inet.port += 2; if (i++ < SERVER_MAX_BIND_COUNT) continue; } fprintf(stderr,"prsocket_test: ERROR - PR_Bind failed\n"); perror("PR_Bind"); failed_already=1; return; } if (PR_GetSockName(sockfd, &netaddr) < 0) { fprintf(stderr,"prsocket_test: ERROR - PR_GetSockName failed\n"); failed_already=1; return; } DPRINTF(("PR_Bind: UDP Server netaddr.inet.ip = 0x%lx, netaddr.inet.port = %d\n", netaddr.inet.ip, netaddr.inet.port)); /* * We can't use the IP address returned by PR_GetSockName in * netaddr.inet.ip because netaddr.inet.ip is returned * as 0 (= PR_INADDR_ANY). */ if (PR_SetNetAddr(PR_IpAddrLoopback, client_domain, PR_ntohs(PR_NetAddrInetPort(&netaddr)), &udp_server_addr) == PR_FAILURE) { fprintf(stderr,"prsocket_test: PR_SetNetAddr failed\n"); failed_already=1; return; } if ((client_domain == PR_AF_INET6) && (server_domain == PR_AF_INET)) PR_ConvertIPv4AddrToIPv6(PR_htonl(INADDR_LOOPBACK), &udp_server_addr.ipv6.ip); /* * Wake up parent thread because server address is bound and made * available in the global variable 'udp_server_addr' */ PR_PostSem(sp->addr_sem); bytes = sp->datalen; in_buf = PR_NEW(buffer); if (in_buf == NULL) { fprintf(stderr,"prsocket_test: failed to alloc buffer struct\n"); failed_already=1; return; } /* * Receive datagrams from clients and send them back, unmodified, to the * clients */ memset(&netaddr, 0 , sizeof(netaddr)); for (i = 0; i < (num_udp_clients * num_udp_datagrams_per_client); i++) { DPRINTF(("UDP_Server: calling PR_RecvFrom client - ip = 0x%lx, port = %d bytes = %d inbuf = 0x%lx, inbuf[0] = 0x%lx\n", netaddr.inet.ip, netaddr.inet.port, bytes, in_buf->data, in_buf->data[0])); rv = PR_RecvFrom(sockfd, in_buf->data, bytes, 0, &netaddr, PR_INTERVAL_NO_TIMEOUT); DPRINTF(("UDP_Server: PR_RecvFrom client - ip = 0x%lx, port = %d bytes = %d inbuf = 0x%lx, inbuf[0] = 0x%lx\n", netaddr.inet.ip, netaddr.inet.port, rv, in_buf->data, in_buf->data[0])); if (rv != bytes) { return; } rv = PR_SendTo(sockfd, in_buf->data, bytes, 0, &netaddr, PR_INTERVAL_NO_TIMEOUT); if (rv != bytes) { return; } } PR_DELETE(in_buf); PR_Close(sockfd); /* * Decrement exit_counter and notify parent thread */ PR_EnterMonitor(sp->exit_mon); --(*sp->exit_counter); PR_Notify(sp->exit_mon); PR_ExitMonitor(sp->exit_mon); DPRINTF(("UDP_Server [0x%x] exiting\n", PR_GetCurrentThread()));}/* * TCP_Client * Client Thread * Connect to the server at the address specified in the argument. * Fill in a buffer, write data to server, read it back and check * for data corruption. * Close the socket for server connection */static void PR_CALLBACKTCP_Client(void *arg){ Client_Param *cp = (Client_Param *) arg; PRFileDesc *sockfd; buffer *in_buf, *out_buf; union PRNetAddr netaddr; PRInt32 bytes, i, j; bytes = cp->datalen; out_buf = PR_NEW(buffer); if (out_buf == NULL) { fprintf(stderr,"prsocket_test: failed to alloc buffer struct\n"); failed_already=1; return; } in_buf = PR_NEW(buffer); if (in_buf == NULL) { fprintf(stderr,"prsocket_test: failed to alloc buffer struct\n"); failed_already=1; return; } netaddr = cp->server_addr; for (i = 0; i < num_tcp_connections_per_client; i++) { if ((sockfd = PR_OpenTCPSocket(client_domain)) == NULL) { fprintf(stderr,"prsocket_test: PR_OpenTCPSocket failed\n"); failed_already=1; return; } if (PR_Connect(sockfd, &netaddr,PR_INTERVAL_NO_TIMEOUT) < 0){ fprintf(stderr, "PR_Connect failed: (%ld, %ld)\n", PR_GetError(), PR_GetOSError()); failed_already=1; return; } for (j = 0; j < num_tcp_mesgs_per_connection; j++) { /* * fill in random data */ memset(out_buf->data, ((PRInt32) (&netaddr)) + i + j, bytes); /* * write to server */#ifdef WINNT if (test_cancelio && (j == 0)) PR_Sleep(PR_SecondsToInterval(12));#endif if (writen(sockfd, out_buf->data, bytes) < bytes) { fprintf(stderr,"prsocket_test: ERROR - TCP_Client:writen\n"); failed_already=1; return; } DPRINTF(("TCP Client [0x%lx]: out_buf = 0x%lx out_buf[0] = 0x%lx\n", PR_GetCurrentThread(), out_buf, (*((int *) out_buf->data)))); if (readn(sockfd, in_buf->data, bytes) < bytes) { fprintf(stderr,"prsocket_test: ERROR - TCP_Client:readn\n"); failed_already=1; return; } /* * verify the data read */ if (memcmp(in_buf->data, out_buf->data, bytes) != 0) { fprintf(stderr,"prsocket_test: ERROR - data corruption\n"); failed_already=1; return; } } /* * shutdown reads and writes */ if (PR_Shutdown(sockfd, PR_SHUTDOWN_BOTH) < 0) { fprintf(stderr,"prsocket_test: ERROR - PR_Shutdown\n"); failed_already=1; } PR_Close(sockfd); } PR_DELETE(out_buf); PR_DELETE(in_buf); /* * Decrement exit_counter and notify parent thread */ PR_EnterMonitor(cp->exit_mon); --(*cp->exit_counter); PR_Notify(cp->exit_mon); PR_ExitMonitor(cp->exit_mon); DPRINTF(("TCP_Client [0x%x] exiting\n", PR_GetCurrentThread()));}/* * UDP_Client * Client Thread * Create a socket and bind an address * Communicate with the server at the address specified in the argument. * Fill in a buffer, write data to server, read it back and check * for data corruption. * Close the socket */static void PR_CALLBACKUDP_Client(void *arg){ Client_Param *cp = (Client_Param *) arg; PRFileDesc *sockfd; buffer *in_buf, *out_buf; union PRNetAddr netaddr; PRInt32 bytes, i, rv; bytes = cp->datalen; out_buf = PR_NEW(buffer); if (out_buf == NULL) { fprintf(stderr,"prsocket_test: failed to alloc buffer struct\n"); failed_already=1; return; } in_buf = PR_NEW(buffer); if (in_buf == NULL) { fprintf(stderr,"prsocket_test: failed to alloc buffer struct\n"); failed_already=1; return; } if ((sockfd = PR_OpenUDPSocket(client_domain)) == NULL) { fprintf(stderr,"prsocket_test: PR_OpenUDPSocket failed\n"); failed_already=1; return; } /* * bind an address for the client, let the system chose the port * number */ memset(&netaddr, 0 , sizeof(netaddr)); if (PR_SetNetAddr(PR_IpAddrAny, client_domain, 0, &netaddr) == PR_FAILURE) { fprintf(stderr,"prsocket_test: PR_SetNetAddr failed\n"); failed_already=1; return; } if (PR_Bind(sockfd, &netaddr) < 0) { fprintf(stderr,"prsocket_test: ERROR - PR_Bind failed\n"); perror("PR_Bind"); return; } if (PR_GetSockName(sockfd, &netaddr) < 0) { fprintf(stderr,"prsocket_test: ERROR - PR_GetSockName failed\n"); failed_already=1; return; } DPRINTF(("PR_Bind: UDP Client netaddr.inet.ip = 0x%lx, netaddr.inet.port = %d\n", netaddr.inet.ip, netaddr.inet.port)); netaddr = cp->server_addr; if (cp->udp_connect) { if (PR_Connect(sockfd, &netaddr,PR_INTERVAL_NO_TIMEOUT) < 0){ fprintf(stderr,"prsocket_test: PR_Connect failed\n"); failed_already=1; return; } } for (i = 0; i < num_udp_datagrams_per_client; i++) { /* * fill in random data */ DPRINTF(("UDP_Client [0x%lx]: out_buf = 0x%lx bytes = 0x%lx\n", PR_GetCurrentThread(), out_buf->data, bytes)); memset(out_buf->data, ((PRInt32) (&netaddr)) + i, bytes); /* * write to server */ if (cp->udp_connect) rv = PR_Send(sockfd, out_buf->data, bytes, 0, PR_INTERVAL_NO_TIMEOUT); else rv = PR_SendTo(sockfd, out_buf->data, bytes, 0, &netaddr, PR_INTERVAL_NO_TIMEOUT); if (rv != bytes) { return; } DPRINTF(("UDP_Client [0x%lx]: out_buf = 0x%lx out_buf[0] = 0x%lx\n", PR_GetCurrentThread(), out_buf, (*((int *) out_buf->data)))); if (cp->udp_connect) rv = PR_Recv(sockfd, in_buf->data, bytes, 0, PR_INTERVAL_NO_TIMEOUT); else rv = PR_RecvFrom(sockfd, in_buf->data, bytes, 0, &netaddr, PR_INTERVAL_NO_TIMEOUT); if (rv != bytes) { return; } DPRINTF(("UDP_Client [0x%lx]: in_buf = 0x%lx in_buf[0] = 0x%lx\n", PR_GetCurrentThread(), in_buf, (*((int *) in_buf->data)))); /* * verify the data read */ if (memcmp(in_buf->data, out_buf->data, bytes) != 0) { fprintf(stderr,"prsocket_test: ERROR - UDP data corruption\n"); failed_already=1; return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -