这里的问题是java客户端在无限循环中保持等待,并且无法获得整个编码消息。
该消息是300 * 300的编码矩阵,就像这样
Terminal Output of encoded Matrix
客户端java代码如下所示:
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Socket;
import java.util.*;
import java.util.*;
public class Tester {
private String encodedMsg="";
public Tester(){
try {
Socket s1 = new Socket("127.0.0.1", 5000);
InputStream s1in = s1.getInputStream();
InputStreamReader isr = new InputStreamReader(s1in);
BufferedReader br = new BufferedReader(isr);
String word="",line="";
while((line=br.readLine())!=null){
word+=line;
}
//String line = br.readLine();
System.out.println("Word is: "+word);
System.out.println("Message received from client is "+this.encodedMsg);
}catch(Exception e){}
}
public static void main(String[] args){
new Tester();
}
}
我认为连接beetwen C server和Java客户端已经很好地建立了,因为当我用br.readline替换while循环只进行一次读取时,输出为'W',即编码消息的第一个字符。
额外:这是一个给定的任务,我需要从服务器c发送一个已处理的bmp文件到客户端java,以便在客户端上用一些UI进行可视化。问题是我需要刷新这个bmp文件,使它看起来像一个gif。 我试图通过读取字节块直接发送图像,但我放弃了在客户端读取块。
如果您需要了解有关代码的更多信息,请告知我们。 谢谢你的时间!!
编辑: 这是服务器端的代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <time.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <math.h>
#define MIN 0
#define MAX 1
#define K 0.00125
#define F_MIN(a,b) (((a)<(b))?(a):(b))
#define F_MAX(a,b) (((a)>(b))?(a):(b))
struct sockaddr_in c_addr;
char fname[100];
/*
* ==================================
* BARRA DE PROGRESO
* ==================================
*/
void barra(int porc, int total, int larg){
int i;
fflush(stdout);
printf("\r[");
for(i=0;i<larg;i++){
if( (100*i)/larg>(100*porc)/total )
putchar('_');
else
putchar('#');
}
printf("] %d%% Completado...",(uint32_t)((float)(100*porc)/(float)(total)) );
}
/*FIN barra()*/
/*
* ==================================
* FUNCIONES RELACIONADAS CON EL PASO
* DE ARGUMENTOS AL PROGRAMA
* ==================================
*/
/*
* Argumentos de entrada y configuracion de getopt
*/
struct args_net{
char name[100];
FILE * file_ptr;
int connfd;
int listenfd;
char encodedMsg[999999];
} net_args;
struct args_t{
uint32_t tamano_grilla;
uint32_t num_pasos;
uint8_t barra;
char* dir_bmp;
uint32_t delta_time;
} args;
static const char *optString = "N:T:m:d:hb";
/*
* Funcion que imprime en stdout el uso
* del programa.
*/
void print_usage(char* name){
printf("Uso: %s -N tamano_grilla -T num_pasos\n", name);
printf("\t [-b] [-m out_dir -d delta_time] [-h]\n");
printf("\nParametros:\n");
printf("\t-N : Tamaño de la grilla de simulación.\n");
printf("\t-T : Nro de pasos de la simulación.\n");
printf("\t-b : Si esta presente, se muestra una barra de progreso.\n" );
printf("\t-m : Si esta presente, almacena imagenes BMP de la simulacion en out_dir.\n" );
printf("\t Cada imagen se crea en el intervalo de tiempo especificado en -d. Por\n" );
printf("\t omisión, delta_time=20\n" );
printf("\t-h : Si esta presente, muestra este mensaje y termina.\n" );
}
/* FIN print_usage()*/
/*
* Funcion que comprueba el ingreso de parametros
* al programa segun seccion 5 del documento LAB1
*/
void check_args(int argc , char **argv){
int opcion;
args.tamano_grilla = 0;
args.num_pasos = 0;
args.barra = 0;
args.dir_bmp = NULL;
args.delta_time = 20;
while ((opcion = getopt (argc, argv, optString)) != -1){
switch (opcion) {
case 'N':
args.tamano_grilla = atoi(optarg);
break;
case 'T':
args.num_pasos = atoi(optarg);
break;
case 'm':
args.dir_bmp = malloc(strlen(optarg)*sizeof(char));
strcpy(args.dir_bmp, optarg);
break;
case 'd':
args.delta_time = atoi(optarg);
break;
case 'b':
args.barra = 1;
break;
case 'h':
default:
print_usage(argv[0]);
exit(EXIT_FAILURE);
}
}
if ( args.tamano_grilla==0 ||
args.num_pasos == 0 ) {
print_usage(argv[0]);
exit(EXIT_FAILURE);
}
}
/* FIN check_args()*/
/*
* ==================================
* FUNCIONES RELACIONADAS CON
* USO DE MATRICES
* ==================================
*/
void matrix_inicializar(float **matrix) {
uint32_t i,j;
for (i = 0; i < args.tamano_grilla; i++) {
if((matrix[i] = (float *)malloc(args.tamano_grilla*sizeof(float))) == NULL){
fprintf(stderr, "Error en malloc en datos_onda[%u]\n",i);
perror("");
exit(EXIT_FAILURE);
}
for ( j = 0; j < args.tamano_grilla; j++) {
matrix[i][j] = 0;
}
}
}
/*FIN matrix_inicializar()*/
void matrix_condicion_inicial(float **matrix){
uint32_t i, j;
uint32_t ii[2], jj[2];
ii[MIN] = (uint32_t)(0.4*args.tamano_grilla);
ii[MAX] = (uint32_t)(0.6*args.tamano_grilla);
jj[MIN] = (uint32_t)(0.4*args.tamano_grilla);
jj[MAX] = (uint32_t)(0.6*args.tamano_grilla);
for(i = ii[MIN]; i < ii[MAX]; i++) {
for(j = jj[MIN]; j < jj[MAX]; j++) {
matrix[i][j] = 20;
}
}
}
/*FIN matrix_condicion_inicial()*/
void matrix_print(float **matrix) {
uint32_t i,j;
for (i = 0; i < args.tamano_grilla; i++) {
for ( j = 0; j < args.tamano_grilla; j++) {
printf("%f\t", matrix[i][j]);
}
printf("\n");
}
}
/*FIN matrix_print()*/
FILE * matrix_to_bmp(float **matrix, char * filename, uint8_t color) {
uint32_t max_RGB = 0xFFFFFF;
uint32_t headers[13];
FILE * outfile;
int extrabytes, paddedsize;
int x, y, n;
extrabytes = 4 - ((args.tamano_grilla * 3) % 4); // How many bytes of padding to add to each
// horizontal line - the size of which must
// be a multiple of 4 bytes.
if (extrabytes == 4)
extrabytes = 0;
paddedsize = ((args.tamano_grilla * 3) + extrabytes) * args.tamano_grilla;
// Headers...
// Note that the "BM" identifier in bytes 0 and 1 is NOT included in these "headers".
headers[0] = paddedsize + 54; // bfSize (whole file size)
headers[1] = 0; // bfReserved (both)
headers[2] = 54; // bfOffbits
headers[3] = 40; // biSize
headers[4] = args.tamano_grilla; // biWidth
headers[5] = args.tamano_grilla; // biHeight
// Would have biPlanes and biBitCount in position 6, but they're shorts.
// It's easier to write them out separately (see below) than pretend
// they're a single int, especially with endian issues...
headers[7] = 0; // biCompression
headers[8] = paddedsize; // biSizeImage
headers[9] = 0; // biXPelsPerMeter
headers[10] = 0; // biYPelsPerMeter
headers[11] = 0; // biClrUsed
headers[12] = 0; // biClrImportant
outfile = fopen(filename, "wb");
//
// Headers begin...
// When printing ints and shorts, we write out 1 character at a time to avoid endian issues.
//
fprintf(outfile, "BM");
for (n = 0; n <= 5; n++) {
fprintf(outfile, "%c", headers[n] & 0x000000FF);
fprintf(outfile, "%c", (headers[n] & 0x0000FF00) >> 8);
fprintf(outfile, "%c", (headers[n] & 0x00FF0000) >> 16);
fprintf(outfile, "%c", (headers[n] & (unsigned int) 0xFF000000) >> 24);
}
// These next 4 characters are for the biPlanes and biBitCount fields.
fprintf(outfile, "%c", 1);
fprintf(outfile, "%c", 0);
fprintf(outfile, "%c", 24);
fprintf(outfile, "%c", 0);
for (n = 7; n <= 12; n++) {
fprintf(outfile, "%c", headers[n] & 0x000000FF);
fprintf(outfile, "%c", (headers[n] & 0x0000FF00) >> 8);
fprintf(outfile, "%c", (headers[n] & 0x00FF0000) >> 16);
fprintf(outfile, "%c", (headers[n] & (unsigned int) 0xFF000000) >> 24);
}
//
// Headers done, now write the data...
//
for (y = args.tamano_grilla - 1; y >= 0; y--) { // BMP image format is written from bottom to top...
for (x = 0; x <= (int)args.tamano_grilla - 1; x++) {
float a = (matrix[x][y]) / 10.0;
uint32_t a_scaled = a*max_RGB;
uint32_t R = 0xFF - ((a_scaled & 0x00ff0000) >> 16);
uint32_t G = 0xFF - ((a_scaled & 0x0000ff00) >> 8);
uint32_t B = 0xFF - ((a_scaled & 0x000000ff));
uint32_t Gray = (R+G+B)/3;
if (color == 0) {
R = Gray;
G = Gray;
B = Gray;
}
fprintf(outfile, "%c", R);
fprintf(outfile, "%c", G);
fprintf(outfile, "%c", B);
}
if (extrabytes){ // See above - BMP lines must be of lengths divisible by 4.
for (n = 1; n <= extrabytes; n++) {
fprintf(outfile, "%c", 0);
}
}
}
fclose(outfile);
/* Archivo Finalizado... se puede enviar ahora */
return outfile;
}
/*FIN matrix_to_bmp()*/
void* SendFileToClient(struct args_net * frame)
{
//int connfd=frame->connfd;
printf("Connection accepted and id: %d\n",frame->connfd);
printf("Connected to Clent: %s:%d\n",inet_ntoa(c_addr.sin_addr),ntohs(c_addr.sin_port));
write(frame->connfd, frame->name,256);
FILE *fp = fopen(frame->name,"rb");
if(fp==NULL)
{
printf("File opern error");
return 0;
}
/* Read data from file and send it */
while(!feof(fp))
{
/* First read file in chunks of 256 bytes */
unsigned char buff[1024]={0};
int nread = fread(buff,1,1024,fp); //lee lo que esta dentro del archivo...
printf("Bytes read %d \n", nread);
/* If read was success, send data. */
if(nread > 0)
{
printf("Sending \n");
write(frame->connfd, buff, nread);
}
if (nread < 1024)
{
if (feof(fp)){
printf("End of file\n");
printf("File transfer completed for id: %d\n",frame->connfd);
}
if (ferror(fp))
printf("Error reading\n");
break;
}
}
printf("Closing Connection for id: %d\n",frame->connfd);
shutdown(frame->connfd,SHUT_WR);
sleep(2);
}
void* Networking(struct args_net *frame){
size_t clen=0;
int err;
pthread_t tid;
clen=sizeof(c_addr);
printf("Waiting...\n");
frame->connfd = accept(frame->listenfd, (struct sockaddr*)&c_addr,&clen); //connfd => clientSocket, en este espera hasta que el cliente solicite conexión.
if(frame->connfd<0){
printf("Error in accept\n");
}
if(write(frame->connfd,frame->encodedMsg,strlen(frame->encodedMsg)!=-1)){
write(frame->connfd, '\n', 1);
printf("%s message send",frame->encodedMsg);
}
}
const char * Encode(float **matrix){
int n=0;
uint32_t i,j;
char word[999999];
int e = 0;
for (i = 0; i < args.tamano_grilla; i++) {
for ( j = 0; j < args.tamano_grilla; j++) {
n= (int)matrix[i][j];
/* 1.- Sign Token */
if(n >= 0){
word[e]='W';
} else {
word[e]='w';
}
e++;
word[e]='.';
e++;
switch(n){
case 0:
word[e]= 'A';
break;
case 1:
word[e]= 'B';
break;
case 2:
word[e]= 'C';
break;
case 3:
word[e]= 'D';
break;
case 4:
word[e]= 'E';
break;
case 5:
word[e]= 'F';
break;
case 6:
word[e]= 'G';
break;
case 7:
word[e]= 'H';
break;
case 8:
word[e]= 'I';
break;
case 9:
word[e]= 'J';
break;
case 10:
word[e]= 'K';
break;
case 11:
word[e]= 'L';
break;
case 12:
word[e]= 'M';
break;
case 13:
word[e]= 'N';
break;
case 14:
word[e]= 'O';
break;
case 15:
word[e]= 'P';
break;
case 16:
word[e]= 'Q';
break;
case 17:
word[e]= 'R';
break;
case 18:
word[e]= 'S';
break;
case 19:
word[e]= 'T';
break;
case 20:
word[e]= 'U';
break;
default:
return(EXIT_FAILURE);
break;
}
e++;
word[e] ='-'; //Number token
e++;
}//End of Row
word[e] ='/'; //Row token
e++;
} //End for
word[e] = '\n';
return &word;
}
int main(int argc , char **argv) {
/*
* H[k][i][j]
* k: k-ésima matriz k={0,1,2}
* i: i-ésima fila de la matriz k
* j: j-ésima columna de la matriz k
*/
struct args_net frame;
struct sockaddr_in serv_addr;
int listenfd = 0,ret;
char sendBuff[1025];
int numrv;
float** H[3];
FILE * file_ptr;
pthread_t thnet;
char fname[256];
uint32_t i,j, t;
uint8_t en_color = 0;
frame.listenfd = socket(AF_INET, SOCK_STREAM, 0); // Creando el Socket TCP
if(frame.listenfd<0)
{
printf("Error in socket creation\n");
exit(2);
}
printf("Socket retrieve success\n");
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(5000);
ret=bind(frame.listenfd, (struct sockaddr*)&serv_addr,sizeof(serv_addr)); //Asignando un puerto al socket
if(ret<0)
{
printf("Error in bind\n");
exit(2);
}
if(listen(frame.listenfd, 10) == -1) //listen(serverSocket, MAXenEspera(creo)) -> Set socket to listen.
{
printf("Failed to listen\n");
return -1;
}
check_args(argc,argv);
H[0] = (float **)malloc(args.tamano_grilla*sizeof(float*));
H[1] = (float **)malloc(args.tamano_grilla*sizeof(float*));
H[2] = (float **)malloc(args.tamano_grilla*sizeof(float*));
if(H[0] == NULL ||
H[1] == NULL||
H[2] == NULL){
perror("Error en malloc() para H[][]");
exit(EXIT_FAILURE);
}
/*
* Create directory to save image
*
*/
if (args.dir_bmp != NULL) {
int8_t res;
char cmd[128];
sprintf(cmd, "rm -rf %s", args.dir_bmp);
res = system(cmd);
if(res == -1){
fprintf(stderr, "No se puede eliminar el directorio de salida %s\n", args.dir_bmp);
perror("");
exit(EXIT_FAILURE);
}
res = mkdirat(AT_FDCWD, args.dir_bmp, S_IRWXU);
if(res == -1){
fprintf(stderr, "No se puede crear el directorio de salida %s\n", args.dir_bmp);
perror("");
exit(EXIT_FAILURE);
}
}
puts("==============================================");
printf("Tamaño grilla : %u\n", args.tamano_grilla);
printf("Nro de pasos : %u\n", args.num_pasos);
if (args.dir_bmp != NULL) {
printf("Directorio salida BMP : %s\n", args.dir_bmp);
printf("Intervalo imágenes : %u\n", args.delta_time);
}
puts("==============================================");
matrix_inicializar(H[0]);
matrix_inicializar(H[1]);
matrix_inicializar(H[2]);
for ( t = 0; t <= args.num_pasos; t++) {
if (args.barra == 1) {
barra(t, args.num_pasos, 50);
}
if (t > 1) {
for ( i = 1; i < (args.tamano_grilla-1); i++) {
for ( j = 1; j < (args.tamano_grilla-1); j++) {
H[t%3][i][j] = 2*H[(t-1)%3][i][j] - H[(t-2)%3][i][j] +
K * (
H[(t-1)%3][i+1][j] +
H[(t-1)%3][i-1][j] +
H[(t-1)%3][i][j-1] +
H[(t-1)%3][i][j+1] -
4*H[(t-1)%3][i][j]
);
}
}
}
else if (t == 1) { /* Interacion 1*/
for ( i = 1; i < (args.tamano_grilla-1); i++) {
for ( j = 1; j < (args.tamano_grilla-1); j++) {
H[1][i][j] = H[0][i][j] +
K * (
H[0][i+1][j] +
H[0][i-1][j] +
H[0][i][j-1] +
H[0][i][j+1] -
4*H[0][i][j]
);
}
}
}
else if (t == 0) {/*Initial Condition*/
matrix_condicion_inicial(H[0]);
}
if (args.dir_bmp == NULL) {
if ( (t % args.delta_time) == 0) {
sprintf(fname, "C%06d.bmp", t);
strcpy(frame.name,fname);
printf("%s\n", frame.name);
printf("%s\n", fname);
//Encoding Matrix
strcpy(frame.encodedMsg,Encode(H[t%3]));
//Network Stuff
Networking(&frame);
}
/*END for()*/
}
while(1){}
printf("\nEnd simulation\n");
return(EXIT_SUCCESS);
}