Java网络编程的那些事儿
我在这里用Java写一个非常简单的网络传输程序。
JNIEXPORT void JNICALL Java_java_io_FileOutputStream_writeBytes(JNIEnv *env, jobject this, jbyteArray bytes, jint off, jint len, jboolean append){ writeBytes(env, this, bytes, off, len, append, fos_fd);}void writeBytes(JNIEnv *env, jobject this, jbyteArray bytes, jint off, jint len, jboolean append, jfieldID fid){ jint n; char stackBuf[BUF_SIZE]; char *buf = NULL; FD fd; if (IS_NULL(bytes)) { JNU_ThrowNullPointerException(env, NULL); return; } if (outOfBounds(env, off, len, bytes)) { JNU_ThrowByName(env, "java/lang/IndexOutOfBoundsException", NULL); return; } if (len == 0) { return; } else if (len > BUF_SIZE) { buf = malloc(len); if (buf == NULL) { JNU_ThrowOutOfMemoryError(env, NULL); return; } } else { buf = stackBuf; } (*env)->GetByteArrayRegion(env, bytes, off, len, (jbyte *)buf); if (!(*env)->ExceptionOccurred(env)) { off = 0; while (len > 0) { fd = GET_FD(this, fid); if (fd == -1) { JNU_ThrowIOException(env, "Stream Closed"); break; } if (append == JNI_TRUE) { n = (jint)IO_Append(fd, buf+off, len); } else { n = (jint)IO_Write(fd, buf+off, len); } if (n == JVM_IO_ERR) { JNU_ThrowIOExceptionWithLastError(env, "Write error"); break; } else if (n == JVM_IO_INTR) { JNU_ThrowByName(env, "java/io/InterruptedIOException", NULL); break; } off += n; len -= n; } } if (buf != stackBuf) { free(buf); }}#define IO_Append handleAppend#define IO_Write handleWriteJNIEXPORT size_t handleWrite(jlong fd, const void *buf, jint len) { return writeInternal(fd, buf, len, JNI_FALSE);}static size_t writeInternal(jlong fd, const void *buf, jint len, jboolean append){ BOOL result = 0; DWORD written = 0; HANDLE h = (HANDLE)fd; if (h != INVALID_HANDLE_VALUE) { OVERLAPPED ov; LPOVERLAPPED lpOv; if (append == JNI_TRUE) { ov.Offset = (DWORD)0xFFFFFFFF; ov.OffsetHigh = (DWORD)0xFFFFFFFF; ov.hEvent = NULL; lpOv = &ov; } else { lpOv = NULL; } result = WriteFile(h, /* File handle to write */ buf, /* pointers to the buffers */ len, /* number of bytes to write */ &written, /* receives number of bytes written */ lpOv); /* overlapped struct */ } if ((h == INVALID_HANDLE_VALUE) || (result == 0)) { return -1; } return (size_t)written;}