I am sending lines through a socket from a client in C, and reading on a server in Java. The best I can manage is that the client send the multiple lines, and when I close the client the server prints all the data in one line. Or to make it that one send then receives, etc. My desire is that the C application sends "Hi" in a loop, and the Java files catches first hi, prints and then catches second and prints. Right now it prints "HiHiHiHi...", but only when the connection is terminated.
I am using oracle socket example as guideline and using another guide for the C client
So reading the socket in Java is:
try {
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(port);
} catch (IOException e) {
System.err.println("Could not listen on port: 4444.");
System.exit(1);
}
Socket clientSocket = null;
try {
clientSocket = serverSocket.accept();
System.out.println("Connected with client");
} catch (IOException e) {
System.err.println("Accept failed.");
System.exit(1);
}
out = new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null) {
System.out.println("RECEIVING " + inputLine);
}
out.close();
in.close();
clientSocket.close();
serverSocket.close();
} catch (IOException ex) {
Logger.getLogger(Connection.class.getName()).log(Level.SEVERE, null, ex);
} finally {
out.close();
}
Trying to write to the socket in a while loop the same string in C:
void connection(void) {
int sockfd, portno;
struct sockaddr_in serv_addr;
struct hostent *server;
/* Set time limit. */
timeout.tv_sec = 0;
timeout.tv_usec = 10;
portno = 4444;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
server = gethostbyname("Localhost");
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,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0)
error("ERROR connecting");
while(1) {
/* Create a descriptor set containing our two sockets. */
FD_ZERO(&fds);
FD_SET(sockfd, &fds);
rc = select(sizeof(fds)*8, &fds, NULL, NULL, &timeout);
if (rc==-1) {
perror("select failed");
}
bzero(buffer,256);
char *buffer2 = "here";
n = write(sockfd,buffer2,strlen(buffer2));
if (n < 0)
error("ERROR writing to socket");
}
}
Your server is waiting for a \n before it prints anything.
Your client isn't sending any \n chars.
You might try:
char *buffer2 = "here"\n;
Related
I'm trying to send and read the reply from the socket with no luck. What I got so far is, connected to the server and read connection reply (header from Ericsson telco exchange) and printed it on System.out. What I need to be able to do is send a command to the exchange and get the reply and that's where I'm stuck. Below is my test code.
Any help is appreciated.
public class ExchangeClientSocket {
public void run() {
try {
int serverPort = 23;
InetAddress host = InetAddress.getByName("my.host.ip.address");
Socket socket = new Socket(host, serverPort);
InputStreamReader isr = new InputStreamReader(socket.getInputStream());
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(isr);
int i;
StringBuffer buffer = new StringBuffer();
while (true) {
i = in.read();
if (i == 60) {
break;
} else {
buffer.append((char) i);
}
}
// this returns the head from exchange
System.out.println(buffer.toString());
out.write("allip;"); // command I want to send to exchange
out.flush();
System.out.println(in.ready()); // this returns false
System.out.println(in.read());
System.out.println("damn..");
buffer = new StringBuffer();
// can't get into this loop
// this is where I want to read the allip response
while ((i = in.read()) != -1) {
i = in.read();
if (i == 60) {
break;
} else {
buffer.append((char) i);
}
}
System.out.println(buffer.toString());
out.close();
in.close();
socket.close();
} catch (UnknownHostException ex) {
ex.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Here is a suggestion on how to get input from the server after writing to the output stream: simply get another input stream from the socket.
So instead of reading from the same stream you create a new stream from the socket after you sent the command and read it.
I would therefore suggest to change your code to this here:
public void run() {
try {
int serverPort = 23;
InetAddress host = InetAddress.getByName("my.host.ip.address");
Socket socket = new Socket(host, serverPort);
InputStreamReader isr = new InputStreamReader(socket.getInputStream());
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(isr);
int i;
StringBuffer buffer = new StringBuffer();
while (true) {
i = in.read();
if (i == 60) {
break;
} else {
buffer.append((char) i);
}
}
// this returns the head from exchange
System.out.println(buffer.toString());
out.write("allip;"); // command I want to send to exchange
out.flush();
// Create a new input stream here !!!
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
buffer = new StringBuffer();
// can't get into this loop
while ((i = in.read()) != -1) {
i = in.read();
if (i == 60) {
break;
} else {
buffer.append((char) i);
}
}
System.out.println(buffer.toString());
out.close();
in.close();
socket.close();
} catch (UnknownHostException ex) {
ex.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
I have 2 socket clients and 2 socket servers, one of each in C and Java and all running on my local machine as processes.
They can all talk to each other successfully except the C socket and Java server. They connect successfully but when I type input into the C client, the enter key does not finish the message and send it to the Java server in the same manner it does when communicating with the C server.
Any insight would be greatly appreciated.
Java Server:
import java.net.*;
import java.io.*;
public class SimpleServer extends Thread
{
private ServerSocket serverSocket;
String clientmsg = "";
public SimpleServer(int port) throws IOException
{
serverSocket = new ServerSocket(port);
serverSocket.setSoTimeout(10000);
}
public void run()
{
while(true)
{
try
{
System.out.println("Waiting for client on port " + serverSocket.getLocalPort() + "...");
Socket server = serverSocket.accept();
System.out.println("Just connected to " + server.getRemoteSocketAddress());
DataInputStream in = new DataInputStream(server.getInputStream());
System.out.println(in.readUTF());
DataOutputStream out = new DataOutputStream(server.getOutputStream());
out.writeUTF("Thank you for connecting to "
+ server.getLocalSocketAddress() + "\nGoodbye!");
server.close();
}
catch(SocketTimeoutException s)
{
System.out.println("Socket timed out!");
break;
}
catch(IOException e)
{
e.printStackTrace();
break;
}
}
}
public static void main(String [] args)
{
int port = Integer.parseInt(args[0]);
try
{
Thread t = new SimpleServer(port);
t.start();
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
C client:
#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <string.h>
#include <netdb.h>
void error(char *msg)
{
perror(msg);
exit(0);
}
int main(int argc, char *argv[])
{
int sockfd, portno;
struct sockaddr_in serv_addr;
struct hostent *server;
int n;
char buffer[256];
if (argc < 3)
{
error("ERROR, no port provided");
}
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
{
error("ERROR opening socket");
}
server = gethostbyname(argv[1]);
if (server == NULL)
{
error("ERROR, host not found\n");
}
bzero((char *) &serv_addr, sizeof(serv_addr));
portno = atoi(argv[2]);
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(portno);
bcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr, server->h_length);
if (connect(sockfd,(struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
error("ERROR connecting to server");
}
printf("Enter a message for the server: ");
bzero(buffer,256);
fgets(buffer,sizeof(buffer),stdin);
n = write(sockfd,buffer,strlen(buffer));
if (n < 0)
{/
error("ERROR writing to socket");
}
bzero(buffer,256);
n = read(sockfd,buffer,255);
if (n < 0)
{
error("ERROR reading from socket");
}
printf("%s\n", buffer);
return 0;
}
I would suggest to use BufferedReader and PrintWriter as follow,
BufferedReader in = new BufferedReader( new InputStreamReader(socket.getInputStream())); // Bufferreader from socket
PrintWriter out = new PrintWriter(socket.getOutputStream(), true); // printwriter from socket
You can simply use them as ,
in.readLine(); // read a line
out.println(); // write a line
So updated code would look like,
Socket server = serverSocket.accept();
System.out.println("Just connected to " + server.getRemoteSocketAddress());
BufferedReader in = new BufferedReader( new InputStreamReader(socket.getInputStream()));
System.out.println(in.readline());
PrintWriter out = new PrintWriter(server.getOutputStream());
out.println("Thank you for connecting to ");
Additionally if i'm correct this approach would fulfill line terminal conditions for both Java and C.
From the readUTF() documentation :
First, two bytes are read and used to construct an unsigned 16-bit integer in exactly the manner of the readUnsignedShort method . This integer value is called the UTF length and specifies the number of additional bytes to be read.
In your C client, you are not sending these two bytes. Of course, this is also true for writeUTF().
Data to be read by readUTF() must be sent by writeUTF(), or something that can produce the same protoco:l: see the Javadoc. As your sender is C this is not practical, so you should use a different read API, for example readLine(), with suitable adjustment at the sender.
I have a PC and the board with a microcontroller in it. PC and board are connected through LAN cable.
I have a ip address and port number of both PC and board. I want to send a string from my PC to the board.I know we have to use socket programe for this.
I have made my PC as the client and board as the server.
when i run the client program i am getting error as connection refused.
The port number of both are the same.
(This is all about sending a TCP packets).
When i use the same client program to communicate with other computer which is made as server it works.
I have got the code in c++ but i want the code in java for this.
A code for this would be helpful
Thanks in advance
Following is an example taken from java doc:
Server Program:
/** EchoServer.java - Echoes the input from client, this needs to be
* executed from microcontroller
*/
import java.net.*;
import java.io.*;
public class EchoServer {
public static void main(String[] args) throws IOException {
if (args.length != 1) {
System.err.println("Usage: java EchoServer <port number>");
System.exit(1);
}
int portNumber = Integer.parseInt(args[0]);
try {
ServerSocket serverSocket =
new ServerSocket(Integer.parseInt(args[0]));
Socket clientSocket = serverSocket.accept();
PrintWriter out =
new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(clientSocket.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null) {
System.out.println("Received: "+inputLine);
System.out.println("Echoing: "+inputLine);
out.println(inputLine);
}
} catch (IOException e) {
System.out.println("Exception caught when trying to listen on port "
+ portNumber + " or listening for a connection");
System.out.println(e.getMessage());
}
}
}
Execute the EchoServer.java in microcontroller like the following:
javac EchoServer.java
java EchoServer 5541
Client Program:
/** EchoClient.java - Sends strings to server
* and displays the echoed string from server
*/
import java.io.*;
import java.net.*;
public class EchoClient {
public static void main(String[] args) throws IOException {
if (args.length != 2) {
System.err.println(
"Usage: java EchoClient <host name> <port number>");
System.exit(1);
}
String hostName = args[0];
int portNumber = Integer.parseInt(args[1]);
try {
Socket echoSocket = new Socket(hostName, portNumber);
PrintWriter out = new PrintWriter(echoSocket.getOutputStream(), true);
BufferedReader in =
new BufferedReader(new InputStreamReader(echoSocket.getInputStream()));
BufferedReader stdIn =new BufferedReader(
new InputStreamReader(System.in));
String userInput;
while ((userInput = stdIn.readLine()) != null) {
out.println(userInput);
System.out.println("echo: " + in.readLine());
}
} catch (UnknownHostException e) {
System.err.println("Don't know about host " + hostName);
System.exit(1);
} catch (IOException e) {
System.err.println("Couldn't get I/O for the connection to " + hostName);
System.exit(1);
}
}
}
Execute the EchoClient.java in PC like the following:
javac EchoClient.java
java EchoClient 110.21.56.74 5541
Here, 110.21.56.74 should be replaced with the IP address of microcontroller.
Program should be terminated from EchoClient by pressing Ctrl+C
Server Program in C
Its been a long while since i worked on C socket programming. The following program from this link worked as expected.
#include<stdio.h>
#include<string.h> //strlen
#include<sys/socket.h>
#include<arpa/inet.h> //inet_addr
#include<unistd.h> //write
int main(int argc , char *argv[])
{
int socket_desc , client_sock , c , read_size;
struct sockaddr_in server , client;
char client_message[2000];
//Create socket
socket_desc = socket(AF_INET , SOCK_STREAM , 0);
if (socket_desc == -1)
{
printf("Could not create socket");
}
puts("Socket created");
//Prepare the sockaddr_in structure
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons( 8888 );
//Bind
if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
{
//print the error message
perror("bind failed. Error");
return 1;
}
puts("bind done");
//Listen
listen(socket_desc , 3);
//Accept and incoming connection
puts("Waiting for incoming connections...");
c = sizeof(struct sockaddr_in);
//accept connection from an incoming client
client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c);
if (client_sock < 0)
{
perror("accept failed");
return 1;
}
puts("Connection accepted");
//Receive a message from client
while( (read_size = recv(client_sock , client_message , 2000 , 0)) > 0 )
{
printf("Received : %s\n",client_message);
printf("Echoing : %s\n",client_message);
//Send the message back to client
write(client_sock , client_message , strlen(client_message));
}
if(read_size == 0)
{
puts("Client disconnected");
fflush(stdout);
}
else if(read_size == -1)
{
perror("recv failed");
}
return 0;
}
Note this C server program uses 8888 as port number.
Is there anyway to set a timeout for a client socket if the client don't get/send any message in a certain time?
here is a sniplet of my code :
try {
mainSocket = new ServerSocket(portNumber);
clientSocket = mainSocket.accept();
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
out = new PrintWriter(clientSocket.getOutputStream(), true);
} catch (IOException ex) {
Logger.error(this, "failed to accept connection. Error was " + ex.getMessage());
}
while (reading) {
try {
char[] arr = new char[2048];
ch = 0;
ch = in.read(arr);
if (ch < 0) {
reading = false;
}
else {
//process message
} catch (IOException ex) {
Logger.error(this, ex);
}
}
now what I want to do is if after x second the clientSocket didn't get any message, it will exit the loop, close the connection and restart accepting connection.
I know how to close the connection and restart accepting connection, but I still can't figure the rest. Is there anyway to accomplish this?
Thanks for the help
I'm trying to get a live flash that lives on a webserver to talk to a local java server, that will live on the clients PC.
I'm trying to achieve this with a socket connection. (port 6000)
Now, at first flash was able to connect, but it just sends <policy-file-request/>. After this nothing happens.
Now, some people at Kirupa suggested to send an cross-domain-policy xml as soon as any connection is established from the java side. http://www.kirupa.com/forum/showthread.php?t=301625
However, my java server just throws the following:
End Exception: java.net.SocketException: Software caused connection abort: recv failed
I've already spend a great amount of time on this subject, and was wondering if anyone here knows what to do?
I found the anwser, So ill post it here in case someone with a simmilar question finds this post.
The moment Flash connects to a local socket server it will send the following:
<policy-file-request/>
We will have to answer with a policy file and immediatly close the connection.
Java:
import java.net.*;
import java.io.*;
public class NetTest {
public static void main(String[] args) {
ServerSocket serverSocket = null;
/* Open a socket to listen */
try {
serverSocket = new ServerSocket(6000);
} catch (IOException e) {
System.out.println("Could not listen on port: 6000");
System.exit(-1);
}
// Try catch a socket to listen on
Socket clientSocket = null;
try {
System.out.println("Waiting for auth on 6000...");
clientSocket = serverSocket.accept();
} catch (IOException e) {
System.out.println("Accept failed: 6000");
System.exit(-1);
}
// Now a stream has been opened...
InputStream in = null;
OutputStream out = null;
try {
in = clientSocket.getInputStream();
out = clientSocket.getOutputStream();
} catch (IOException e) {
System.out.println("Failed to get streams.");
System.exit(-1);
}
System.out.println("Socket connection incoming!");
// Keep going while we can...
byte b[] = new byte[100];
int offset = 0;
String s;
try {
boolean done = false;
boolean auth = false;
String protocol_target = "<policy-file-request/>";
byte[] p_bytes = protocol_target.getBytes();
int result;
while (!done) {
if (in.read(b, offset, 1) == -1)
done = true;
else {
if (!auth) {
++offset;
b[offset] = 0;
if (offset != p_bytes.length) {
System.out.println("Waiting for protocol data... ("
+ offset + "/" + p_bytes.length + ")");
} else {
// Compare byte data
for (int i = 0; i < p_bytes.length; ++i) {
System.out.print(b[i] + " ");
}
System.out.print("\n");
System.out.flush();
for (int i = 0; i < p_bytes.length; ++i) {
System.out.print(p_bytes[i] + " ");
}
System.out.print("\n");
System.out.flush();
boolean match = true;
for (int i = 0; i < p_bytes.length; ++i) {
if (b[i] != p_bytes[i]) {
match = false;
System.out
.println("Mismatch on " + i + ".");
}
}
if (match)
auth = true;
else {
System.out.println("Bad protocol input.");
System.exit(-1);
}
}
// Auth
if (auth) {
System.out.println("Authing...");
s = "<?xml version=\"1.0\"?><cross-domain-policy><allow-access-from domain='*' to-ports='6000' /></cross-domain-policy>";
b = s.getBytes();
out.write(b, 0, b.length);
b[0] = 0;
out.write(b, 0, 1); // End
out.flush();
offset = 0;
b = new byte[100];
b[0] = 0;
auth = true;
System.out.println("Auth completed.");
}
}
}
}
} catch (IOException e) {
System.out.println("Stream failure: " + e.getMessage());
System.exit(-1);
}
// Finished.
try {
in.close();
out.close();
clientSocket.close();
} catch (Exception e) {
System.out.println("Failed closing auth stream: " + e.getMessage());
System.exit(-1);
}
// Try catch a socket to listen on for data
try {
System.out.println("Waiting on 6000 fo data...");
clientSocket = serverSocket.accept();
} catch (IOException e) {
System.out.println("Accept failed: 6000");
System.exit(-1);
}
// Now a stream has been opened...
in = null;
out = null;
try {
in = clientSocket.getInputStream();
out = clientSocket.getOutputStream();
} catch (IOException e) {
System.out.println("Failed to get streams.");
System.exit(-1);
}
System.out.println("Socket data connection waiting.");
// Echo
try {
boolean done = false;
while (!done) {
if (in.read(b, offset, 1) == -1)
done = true;
else {
b[1] = 0;
s = new String(b);
System.out.print(s);
System.out.flush();
}
}
} catch (IOException e) {
System.out.println("Failed echo stream: " + e.getMessage());
System.exit(-1);
}
// Finished.
try {
in.close();
out.close();
clientSocket.close();
serverSocket.close();
} catch (Exception e) {
System.out.println("Failed closing stream: " + e.getMessage());
System.exit(-1);
}
}
}