420 */
421 JNIEXPORT void JNICALL
422 Java_java_net_TwoStacksPlainDatagramSocketImpl_send
423 (JNIEnv *env, jobject this, jobject packet)
424 {
425 char BUF[MAX_BUFFER_LEN];
426 char *fullPacket;
427 jobject fdObj;
428 jint fd;
429
430 jobject iaObj;
431 jint family;
432
433 jint packetBufferOffset, packetBufferLen, packetPort;
434 jbyteArray packetBuffer;
435 jboolean connected;
436
437 SOCKETADDRESS rmtaddr;
438 struct sockaddr *addrp = 0;
439 int addrlen = 0;
440
441 if (IS_NULL(packet)) {
442 JNU_ThrowNullPointerException(env, "null packet");
443 return;
444 }
445
446 iaObj = (*env)->GetObjectField(env, packet, dp_addressID);
447
448 packetPort = (*env)->GetIntField(env, packet, dp_portID);
449 packetBufferOffset = (*env)->GetIntField(env, packet, dp_offsetID);
450 packetBuffer = (jbyteArray)(*env)->GetObjectField(env, packet, dp_bufID);
451 connected = (*env)->GetBooleanField(env, this, pdsi_connected);
452
453 if (IS_NULL(iaObj) || IS_NULL(packetBuffer)) {
454 JNU_ThrowNullPointerException(env, "null address || null buffer");
455 return;
456 }
457
458 family = getInetAddress_family(env, iaObj);
459 JNU_CHECK_EXCEPTION(env);
498 * than 2048 bytes into several operations of size 2048.
499 * This saves a malloc()/memcpy()/free() for big
500 * buffers. This is OK for file IO and TCP, but that
501 * strategy violates the semantics of a datagram protocol.
502 * (one big send) != (several smaller sends). So here
503 * we *must* alloc the buffer. Note it needn't be bigger
504 * than 65,536 (0xFFFF) the max size of an IP packet.
505 * anything bigger is truncated anyway.
506 */
507 fullPacket = (char *)malloc(packetBufferLen);
508 if (!fullPacket) {
509 JNU_ThrowOutOfMemoryError(env, "Send buf native heap allocation failed");
510 return;
511 }
512 } else {
513 fullPacket = &(BUF[0]);
514 }
515
516 (*env)->GetByteArrayRegion(env, packetBuffer, packetBufferOffset,
517 packetBufferLen, (jbyte *)fullPacket);
518 if (sendto(fd, fullPacket, packetBufferLen, 0, addrp,
519 addrlen) == SOCKET_ERROR)
520 {
521 NET_ThrowCurrent(env, "Datagram send failed");
522 }
523
524 if (packetBufferLen > MAX_BUFFER_LEN) {
525 free(fullPacket);
526 }
527 }
528
529 /*
530 * check which socket was last serviced when there was data on both sockets.
531 * Only call this if sure that there is data on both sockets.
532 */
533 static int checkLastFD (JNIEnv *env, jobject this, int fd, int fd1) {
534 int nextfd, lastfd = (*env)->GetIntField(env, this, pdsi_lastfdID);
535 if (lastfd == -1) {
536 /* arbitrary. Choose fd */
537 (*env)->SetIntField(env, this, pdsi_lastfdID, fd);
538 return fd;
539 } else {
540 if (lastfd == fd) {
541 nextfd = fd1;
542 } else {
543 nextfd = fd;
1140 JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
1141 "Receive timed out");
1142 } else if (ret == -1) {
1143 JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
1144 "Socket closed");
1145 }
1146 if (packetBufferLen > MAX_BUFFER_LEN) {
1147 free(fullPacket);
1148 }
1149 return;
1150 }
1151 }
1152
1153 /*
1154 * An ICMP port unreachable was received but we are
1155 * not connected so ignore it.
1156 */
1157 retry = TRUE;
1158 }
1159 }
1160 } while (retry);
1161
1162 /* truncate the data if the packet's length is too small */
1163 if (n > packetBufferLen) {
1164 n = packetBufferLen;
1165 }
1166 if (n < 0) {
1167 errorCode = WSAGetLastError();
1168 /* check to see if it's because the buffer was too small */
1169 if (errorCode == WSAEMSGSIZE) {
1170 /* it is because the buffer is too small. It's UDP, it's
1171 * unreliable, it's all good. discard the rest of the
1172 * data..
1173 */
1174 n = packetBufferLen;
1175 } else {
1176 /* failure */
1177 (*env)->SetIntField(env, packet, dp_lengthID, 0);
1178 }
1179 }
|
420 */
421 JNIEXPORT void JNICALL
422 Java_java_net_TwoStacksPlainDatagramSocketImpl_send
423 (JNIEnv *env, jobject this, jobject packet)
424 {
425 char BUF[MAX_BUFFER_LEN];
426 char *fullPacket;
427 jobject fdObj;
428 jint fd;
429
430 jobject iaObj;
431 jint family;
432
433 jint packetBufferOffset, packetBufferLen, packetPort;
434 jbyteArray packetBuffer;
435 jboolean connected;
436
437 SOCKETADDRESS rmtaddr;
438 struct sockaddr *addrp = 0;
439 int addrlen = 0;
440 int ret;
441
442 if (IS_NULL(packet)) {
443 JNU_ThrowNullPointerException(env, "null packet");
444 return;
445 }
446
447 iaObj = (*env)->GetObjectField(env, packet, dp_addressID);
448
449 packetPort = (*env)->GetIntField(env, packet, dp_portID);
450 packetBufferOffset = (*env)->GetIntField(env, packet, dp_offsetID);
451 packetBuffer = (jbyteArray)(*env)->GetObjectField(env, packet, dp_bufID);
452 connected = (*env)->GetBooleanField(env, this, pdsi_connected);
453
454 if (IS_NULL(iaObj) || IS_NULL(packetBuffer)) {
455 JNU_ThrowNullPointerException(env, "null address || null buffer");
456 return;
457 }
458
459 family = getInetAddress_family(env, iaObj);
460 JNU_CHECK_EXCEPTION(env);
499 * than 2048 bytes into several operations of size 2048.
500 * This saves a malloc()/memcpy()/free() for big
501 * buffers. This is OK for file IO and TCP, but that
502 * strategy violates the semantics of a datagram protocol.
503 * (one big send) != (several smaller sends). So here
504 * we *must* alloc the buffer. Note it needn't be bigger
505 * than 65,536 (0xFFFF) the max size of an IP packet.
506 * anything bigger is truncated anyway.
507 */
508 fullPacket = (char *)malloc(packetBufferLen);
509 if (!fullPacket) {
510 JNU_ThrowOutOfMemoryError(env, "Send buf native heap allocation failed");
511 return;
512 }
513 } else {
514 fullPacket = &(BUF[0]);
515 }
516
517 (*env)->GetByteArrayRegion(env, packetBuffer, packetBufferOffset,
518 packetBufferLen, (jbyte *)fullPacket);
519 if (ret = sendto(fd, fullPacket, packetBufferLen, 0, addrp,
520 addrlen) == SOCKET_ERROR)
521 {
522 NET_ThrowCurrent(env, "Datagram send failed");
523 }
524
525 if (ret > 0) {
526 JVM_callFileWriteBytes(env, ret);
527 }
528
529 if (packetBufferLen > MAX_BUFFER_LEN) {
530 free(fullPacket);
531 }
532 }
533
534 /*
535 * check which socket was last serviced when there was data on both sockets.
536 * Only call this if sure that there is data on both sockets.
537 */
538 static int checkLastFD (JNIEnv *env, jobject this, int fd, int fd1) {
539 int nextfd, lastfd = (*env)->GetIntField(env, this, pdsi_lastfdID);
540 if (lastfd == -1) {
541 /* arbitrary. Choose fd */
542 (*env)->SetIntField(env, this, pdsi_lastfdID, fd);
543 return fd;
544 } else {
545 if (lastfd == fd) {
546 nextfd = fd1;
547 } else {
548 nextfd = fd;
1145 JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
1146 "Receive timed out");
1147 } else if (ret == -1) {
1148 JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
1149 "Socket closed");
1150 }
1151 if (packetBufferLen > MAX_BUFFER_LEN) {
1152 free(fullPacket);
1153 }
1154 return;
1155 }
1156 }
1157
1158 /*
1159 * An ICMP port unreachable was received but we are
1160 * not connected so ignore it.
1161 */
1162 retry = TRUE;
1163 }
1164 }
1165 if (n > 0) {
1166 JVM_callNetworkReadBytes(env, n);
1167 }
1168 } while (retry);
1169
1170 /* truncate the data if the packet's length is too small */
1171 if (n > packetBufferLen) {
1172 n = packetBufferLen;
1173 }
1174 if (n < 0) {
1175 errorCode = WSAGetLastError();
1176 /* check to see if it's because the buffer was too small */
1177 if (errorCode == WSAEMSGSIZE) {
1178 /* it is because the buffer is too small. It's UDP, it's
1179 * unreliable, it's all good. discard the rest of the
1180 * data..
1181 */
1182 n = packetBufferLen;
1183 } else {
1184 /* failure */
1185 (*env)->SetIntField(env, packet, dp_lengthID, 0);
1186 }
1187 }
|