c prog socket connect to java program  
Author Message
amxli





PostPosted: 2004-7-20 7:21:00 Top

java-programmer, c prog socket connect to java program my c program wants to send a message to java program through socket.
The problem i have is the message received by java socket server
is not a complete message most of time. Please see my attachment of
c prog and java program.

Thank you very much for your kind help.

Mei


Here is my c client program:

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>


void error(char *msg)
{
perror(msg);
exit(0);
}
int main(int argc,char **argv) {
FILE *fileIn; /* declare a FILE pointer */
FILE *fileOut; /* declare a FILE pointer */
char buffer[8000];
char line[4000];
char c;
int create_socket;
int bufsize = 1024;
int len=0;
int cnt=0;
char *cmd = "XML2Marc,/export/home/mml/Marc4jProg/Marc4jTest/testcase/exporttsamnonowner5.xsl,MARC8,";
int sockfd, portno, n;
struct sockaddr_in serv_addr;
struct hostent *server;
fileOut = fopen("data/out.xml", "w");


if(fileIn==NULL) {
printf("Error: can't open file.\n");
return 1;
}
else {

strcat(buffer,cmd);

if ( (fileIn = fopen("data/test.xml", "r")) != NULL) {
fgets(line, sizeof(line), fileIn);
}

fclose(fileIn);

strcat(buffer,line);
strcat(buffer,"\r\n");

len= strlen(line);
printf("debug::buffer:: %d \n %s", len, buffer);
fprintf(fileOut,"%s", buffer);


portno = 5088;
sockfd = socket(AF_INET, SOCK_STREAM, 0);

if (sockfd < 0)
error("ERROR opening socket");
server = gethostbyname("hopper2.rlg.org");
if (server == NULL) {
fprintf(stderr,"ERROR, no such host\n");
exit(0);
}

bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
bcopy((char *)server->h_addr,
(char *)&serv_addr.sin_addr.s_addr,
server->h_length);

serv_addr.sin_port = htons(portno);
if (connect(sockfd,&serv_addr,sizeof(serv_addr)) < 0)
error("ERROR connecting");
n = write(sockfd,buffer,strlen(buffer));
sleep(20);
if (n < 0)
error("ERROR writing to socket");
bzero(buffer,4000);
printf(" test ");

n = read(sockfd,buffer,4000);
if (n < 0)
error("ERROR reading from socket");
printf("output::: %s\n",buffer);
printf("%d",n);
if(strlen(buffer)<2){ //try another time
n = read(sockfd,buffer,4000);
if (n < 0)
error("ERROR reading from socket");
printf("output::: %s\n",buffer);
}
printf("File opened. Now closing it...\n");
fclose(fileIn);
fclose(fileOut);
return 0;
}
}


and here is the partial java program:

public class Marc4jWorker extends Thread{
....
public void run(){

char[] ln=new char[8000];
OutputStream outbound=null;
InputStream inbound =null;

while(true){
String line="";
int cc=0;
String action= null;
String style=null;
String encode="UTF8";
String xmlstr=null;
//String line;

try{
inbound = client.getInputStream();
int btecnt = inbound.available();
byte[] bf=null;

if(btecnt<=0)
continue;
else {
bf = new byte[btecnt];
inbound.read(bf);
}

//why the message is incomplete ????
System.out.println("server: input bytes length:"+bf.length);
line =new String(bf);
if(Config.ENDREQ.equalsIgnoreCase(line)){
outbound.close();
client.close();
System.err.println("request end");
break;
}

//line = bf.toString(Config.ENC_UTF8);
int ps_firstcomma =line.indexOf(',',0);
int ps_secondcomma = 0;
int sz=line.length();

if(ps_firstcomma>0 && ps_firstcomma<sz-1)
action=line.substring(0,ps_firstcomma).trim();
ps_secondcomma=line.indexOf(',',ps_firstcomma+1);
if(ps_firstcomma<ps_secondcomma && ps_secondcomma>0 &&
ps_secondcomma<sz-1)
style=line.substring(ps_firstcomma+1,ps_secondcomma).trim();
ps_firstcomma=ps_secondcomma+1;
ps_secondcomma=line.indexOf(',',ps_firstcomma+1);

if(ps_secondcomma>0 && ps_secondcomma<sz-1){
encode=line.substring(ps_firstcomma,ps_secondcomma).trim();
Log.println("server encode:"+encode);

//for action is xml2marc, input xml encoding is always UTF8
if(action.equalsIgnoreCase("xml2marc")){
xmlstr= new
String(bf,Config.ENC_UTF8).substring(ps_secondcomma+1);

}else if("marc2xml".equalsIgnoreCase(action)){
if(Config.ENC_UTF8.equalsIgnoreCase(encode))
xmlstr= new
String(bf,Config.ENC_UTF8).substring(ps_secondcomma+1);
else
xmlstr= new
String(bf,Config.ENC_ISO).substring(ps_secondcomma+1);

}else{
System.out.println("Unsupported Action!");
continue;
}
}

FileOutputStream fout =null;

String rs = null;
if(action.equalsIgnoreCase("xml2marc")){
if(Config.ENC_UTF8.equalsIgnoreCase(encode)){
fout = new FileOutputStream("/tmp/servertest.input",true);
fout.write(xmlstr.getBytes(Config.ENC_UTF8));
fout.close();
}
else {
fout = new FileOutputStream("/tmp/servertest.input",true);
fout.write(xmlstr.getBytes(Config.ENC_ISO));
fout.close();

}
rs = Xml2Marc.toMarc(style,encode,xmlstr);

}else if(action.equalsIgnoreCase("marc2xml")){
if(Config.ENC_UTF8.equalsIgnoreCase(encode)){
fout = new FileOutputStream("/tmp/servertest.input",true);
fout.write(xmlstr.getBytes(Config.ENC_UTF8));
fout.close();
}
else {
fout = new FileOutputStream("/tmp/servertest.input",true);
fout.write(xmlstr.getBytes(Config.ENC_ISO));
fout.close();
}
rs = Marc2Xml.toXML(style,encode,xmlstr);
}

fout = new FileOutputStream("/tmp/servertest.output");
outbound =client.getOutputStream();
if(rs==null || rs.length()==0)
rs="00005";

if("Xml2Marc".equalsIgnoreCase(action)){
if(encode.equalsIgnoreCase(Config.ENC_UTF8)){
outbound.write(rs.getBytes(Config.ENC_UTF8));
fout.write(rs.getBytes(Config.ENC_UTF8));
}else{
fout.write(rs.getBytes(Config.ENC_ISO));
outbound.write(rs.getBytes(Config.ENC_ISO));
}
}else if("Marc2Xml".equalsIgnoreCase(action)){
outbound.write(rs.getBytes(Config.ENC_UTF8));
fout.write(rs.getBytes(Config.ENC_UTF8));
}

outbound.flush();
fout.close();


} catch (IOException e) {
Log.println("Read failed"+e.toString());
System.exit(-1);
}catch(Exception e){
Log.println("server error:"+e.toString());
}

}


}
 
Roedy Green





PostPosted: 2004-7-20 7:54:00 Top

java-programmer >> c prog socket connect to java program On 19 Jul 2004 16:20:58 -0700, email***@***.com (Mei Li) wrote or
quoted :

>my c program wants to send a message to java program through socket.
>The problem i have is the message received by java socket server
>is not a complete message most of time. Please see my attachment of
>c prog and java program.

did you remember to flush?

See http://mindprod.com/fileio.html

see socket write.

--
Canadian Mind Products, Roedy Green.
Coaching, problem solving, economical contract programming.
See http://mindprod.com/jgloss/jgloss.html for The Java Glossary.
 
Gordon Beaton





PostPosted: 2004-7-20 13:16:00 Top

java-programmer >> c prog socket connect to java program [ invalid group com.lang.java.developer removed ]

On 19 Jul 2004 16:20:58 -0700, Mei Li wrote:
> my c program wants to send a message to java program through socket.
> The problem i have is the message received by java socket server
> is not a complete message most of time. Please see my attachment of
> c prog and java program.

TCP does not respect message boundaries. It sends data in chunks whose
size depend on a number of things beyond the control of your
application.

Neither read() (nor write()) guarantee that you will read (or write)
the requested number of bytes. Use the value returned by the function,
and read (or write) again in a loop until the entire message has been
transferred.

> int btecnt = inbound.available();

available() only reports how many bytes have already been received by
the underlying socket layer, and are available to be read immediately
by your application. It is unrelated to the size of the message, which
the remote is probably still sending.

You need to read() repeatedly until the entire message has been
received. Don't throw away the return value of read(). Either read in
a loop, or use DataInputStream.readFully() if you know the length of
the message in advance.

/gordon

--
[ do not email me copies of your followups ]
g o r d o n + n e w s @ b a l d e r 1 3 . s e
 
 
Thomas Schodt





PostPosted: 2004-7-20 18:01:00 Top

java-programmer >> c prog socket connect to java program Gordon Beaton wrote:

> TCP does not respect message boundaries. It sends data in chunks whose
> size depend on a number of things beyond the control of your
> application.
>
> Neither read() [nor write()] guarantee that you will read (or write)
> the requested number of bytes. Use the value returned by the function,
> and read (or write) again in a loop until the entire message has been
> transferred.

java.net.Socket.getOutputStream().write() returns void.

So the Java socket code implements this loop for you;
all your data is written or an exception is thrown.

You still need to loop on write() in your C code.