My assignment requiers me to write an server in c but client in java. I need to send some integer to my client as instructions. They can connected smoothly but my java client cannot Receive the integer send from c server. there is only two possibilities: my c server did not send the Number out OR my client does not Receive the integer correctly. The c server is able to loop as I type in since the printf and scanf is executed while nothing happends on the client side.
I am stuck here, any help will be appreciate!
=========================================================================
UPDATE:
I correct the main class in java where the class name of the client into dotClient, and my client was able to conncected and read the inputs from the server.
I have try to send an 'int' directly in the server side, but When the client(java) use DataInputStream.ReadInt(), it returns a randomly big number as if the size of int in c and size of int in java is not matched.When I use a c client to do the same job, it works normal. So there is Hidden Problem for using dataInputStream directly with a c server, as I tried readShort() and ReadLong() as well.
As suggested, I use bufferReader.
And send string in server side, and perse it into int in client.
it works.
hère is my updated c code
#define PORT 55555
int main(int argc, char const *argv[])
{
int server_fd, new_socket, valread;
struct sockaddr_in address;
int opt = 1;
int addrlen = sizeof(address);
char buffer[1024];
int returnSend = 0;
// Creating socket file descriptor
if (
(server_fd = socket(AF_INET, SOCK_STREAM, 0))
== 0)
{
perror("socket failed");
exit(EXIT_FAILURE);
}
printf("%s\n", "Socket created!");
// Forcefully attaching socket to the port 8080
if (setsockopt(server_fd, SOL_SOCKET,
SO_REUSEPORT, &opt, sizeof(opt)))
{
perror("setsockopt");
exit(EXIT_FAILURE);
}
printf("Socket attached!\n");
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons( PORT );
// Forcefully attaching socket to the port 8080
if (bind(server_fd,
(struct sockaddr *)&address,
sizeof(address))<0)
{
perror("bind failed");
exit(EXIT_FAILURE);
}
printf("socket binded!\n");
if (listen(server_fd, 3) < 0)
{
perror("listen");
exit(EXIT_FAILURE);
}
printf("socket listened!\n");
if ((new_socket = accept(server_fd,
(struct sockaddr *)&address,
(socklen_t*)&addrlen))<0)
{
perror("accept");
exit(EXIT_FAILURE);
}// Socket formulated !
do{
fgets(buffer, sizeof(buffer), stdin);
returnSend = write(new_socket , buffer , strlen(buffer));
printf("Sending: %sReturn returnSend: %d.\n", buffer,returnSend);
} while (1);
return 0;
}
hère is my updated java client
import java.net.*;
import java.io.*;
public class dotClient
{
// initialize socket and input output streams
private Socket echoSocket= null;
private BufferedReader input = null;
// constructor to put ip address and port
public dotClient(String address, int port)
{
// establish a connection
try
{
echoSocket = new Socket(address, port);
System.out.println("Connected");
input =
new BufferedReader(
new InputStreamReader(echoSocket.getInputStream()));
}
catch(UnknownHostException u)
{
System.out.println("exception 1: "+u);
}
catch(IOException i)
{
System.out.println("exception 2: "+i);
}
int number = 0;
String line = "";
// keep reading until read neagaive integer
try
{
while ((line = input.readLine()) != null)
{
number = Integer.parseInt(line);
System.out.println("String is :"+line);
System.out.println("number is :"+number);
}
}
catch(IOException i)
{
System.out.println("Exception 3: "+i);
}
// close the connection
try
{
input.close();
out.close();
echoSocket.close();
System.out.println("Connection closed!");
}
catch(IOException i)
{
System.out.println("Exception 4: "+i);
}
}
public static void main(String args[])
{
dotClient client = new dotClient("192.168.0.3", 55555);
}
}
In your main method you are creating a Client instance but your class is called dotClient. You might want to ensure you are creating an instance of your class dotClient. Otherwise I agree with the previous comments and would suggest BufferedReader and BufferedWriter/PrintWriter for the IO.
Do any of your try blocks catch an exception on the client? Check the return value of send(new_socket , &number , size(number) , 0 ); on the server to make sure the data was actually sent for more info checkout http://man7.org/linux/man-pages/man2/send.2.html.
Related
In some tutoral-based codes, I connected a C# web application to a Java socket server through my web application's WebMethod in a webservice. Unfortunately this is happening pretty slowly. For example, when the Java server echoes some data to the C# client I get the following results:
Size of data sent= 32MB, total time= 980 ms (no problem)
Size of data sent= 4MB, total time= 530 ms (becomes somewhat slower)
Size of data sent= 1MB, total time= 520 ms (absolutely bottlenecked)
Size of data sent= 1kB, total time= 516 ms (this must be some constant latency of something)
I've read that people can make real-time communications (~60/s) and sometimes even millions of streams/s with some server apps. What could be the problem with my implementation? It is sending multiple messages over a single open connection, so the object creation overhead should only show up for the first message? Why am I getting ~500 ms overhead on my messaging?
The C# webmethod is initiated when the web-app starts and connects to the same Java server for every call to this webmethod.
public static IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
public static IPAddress ipAddress = ipHostInfo.AddressList[0];
public static IPEndPoint remoteEP = new IPEndPoint(ipAddress, 9999);
// Create a TCP/IP socket.
public static Socket sender = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
public static int z = 0;
[WebMethod]
public BenchmarkData_ StartClient()
{
lock(lck)
{
z++;
if (z == 1)
{
sender.Connect(remoteEP);
}
}
int bytesRec = 0;
int boy = 0;
byte[] bytes = new byte[1024 * 1024];
int bytesSent = 0;
SocketFlags sf = new SocketFlags();
Stopwatch sw = new Stopwatch(); Stopwatch sw2 = new Stopwatch();
#region r
lock (lck)
{
sw.Start();
// Data buffer for incoming data.
// Connect to a remote device.
try
{
// Establish the remote endpoint for the socket.
// This example uses port 11000 on the local computer.
// Create a TCP/IP socket.
sender.ReceiveBufferSize = 1024 * 1024;
sender.ReceiveTimeout = 1;
// Connect the socket to the remote endpoint. Catch any errors.
try
{
Console.WriteLine("Socket connected to {0}", sender.RemoteEndPoint.ToString());
// Encode the data string into a byte array.
byte[] msg = Encoding.ASCII.GetBytes("This is a test<EOF>");
// Send the data through the socket.
bytesSent = sender.Send(msg);
// Receive the response from the remote device.
sw.Stop();
sw2.Start();
while ((bytesRec = sender.Receive(bytes)) > 0)
{
boy += bytesRec;
}
Console.WriteLine("Echoed test = {0}", Encoding.ASCII.GetString(bytes, 0, bytesRec));
// Release the socket.
// sender.Shutdown(SocketShutdown.Both);
// sender.Close();
sw2.Stop();
}
catch (ArgumentNullException ane)
{
Console.WriteLine("ArgumentNullException : {0}", ane.ToString());
}
catch (SocketException se)
{
Console.WriteLine("SocketException : {0}", se.ToString());
}
catch (Exception e)
{
Console.WriteLine("Unexpected exception : {0}", e.ToString());
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
#endregion
return new BenchmarkData_() { .... };
}
Here is the Java code (half-pseudo code)
serverSocket=new ServerSocket(port); // in listener thread
Socket socket=serverSocket.accept(); // in listener thread
// in a dedicated thread per connection made:
out=new BufferedOutputStream( socket.getOutputStream());
in=new DataInputStream(socket.getInputStream());
boolean reading=true;
ArrayList<Byte> incoming=new ArrayList<Byte>();
while (in.available() == 0)
{
Thread.sleep(3);
}
while (in.available() > 0)
{
int bayt=-2;
try {
bayt=in.read();
} catch (IOException e) { e.printStackTrace(); }
if (bayt == -1)
{
reading = false;
}
else
{
incoming.add((byte) bayt);
}
}
byte [] incomingBuf=new byte[incoming.size()];
for(int i = 0; i < incomingBuf.length; i++)
{
incomingBuf[i] = incoming.get(i);
}
msg = new String(incomingBuf, StandardCharsets.UTF_8);
if (msg.length() < 8192)
System.out.println("Socket Thread: "+msg);
else
System.out.println("Socket Thread: long msg.");
OutputStreamWriter outW = new OutputStreamWriter(out);
System.out.println(socket.getReceiveBufferSize());
outW.write(testStr.toString()); // 32MB, 4MB, ... 1kB versions
outW.flush();
Problem solved in replacement of
while ((bytesRec = sender.Receive(bytes))>0)
{
boy += bytesRec;
}
with
while (sender.Available <= 0) ;
while (sender.Available>0)
{
bytesRec = sender.Receive(bytes);
boy += bytesRec;
}
now its in microseconds for 1kB reads instead of 500ms. Because its checking a single integer instead of trying to read on whole buffer? Maybe. But it now doesnt read all the message sent from server. It needs some type of header to know how much to read on. Reads about several kilobytes even when server sends megabytes.
When server sends 3MB and client reads exactly same amount, it takes 30ms. Both in same machine. Trying to read more than server has sent, (even a single byte), raises an exception so TCP really sends exact same amount needed by client.
Java server socket
In the following code:
https://docs.oracle.com/javase/tutorial/networking/sockets/examples/KnockKnockServer.java
import java.net.*;
import java.io.*;
public class KnockKnockServer {
public static void main(String[] args) throws IOException {
if (args.length != 1) {
System.err.println("Usage: java KnockKnockServer <port number>");
System.exit(1);
}
int portNumber = Integer.parseInt(args[0]);
try (
ServerSocket serverSocket = new ServerSocket(portNumber);
Socket clientSocket = serverSocket.accept();
PrintWriter out =
new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(clientSocket.getInputStream()));
) {
String inputLine, outputLine;
// Initiate conversation with client
KnockKnockProtocol kkp = new KnockKnockProtocol();
outputLine = kkp.processInput(null);
out.println(outputLine);
while ((inputLine = in.readLine()) != null) {
outputLine = kkp.processInput(inputLine);
out.println(outputLine);
if (outputLine.equals("Bye."))
break;
}
} 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());
}
}
}
when the server sends its response to the client socket, it writes to the "PrintWriter" "out" using the "println()" method (line 63).
I have tried using the "print()" method instead.
In the "println()" case, the client socket receives the message properly.
In the "print()" case, the client socket doesn't receive anything.
Is this normal?
Is it required to send an EOF, a CR LF (in my case) (10 and 13 ASCII characters) at the end of the message?
Is it documented somewhere?
Winsock
In the following code:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms737591%28v=vs.85%29.aspx
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
// Need to link with Ws2_32.lib, Mswsock.lib, and Advapi32.lib
#pragma comment (lib, "Ws2_32.lib")
#pragma comment (lib, "Mswsock.lib")
#pragma comment (lib, "AdvApi32.lib")
#define DEFAULT_BUFLEN 512
#define DEFAULT_PORT "27015"
int __cdecl main(int argc, char **argv)
{
WSADATA wsaData;
SOCKET ConnectSocket = INVALID_SOCKET;
struct addrinfo *result = NULL,
*ptr = NULL,
hints;
char *sendbuf = "this is a test";
char recvbuf[DEFAULT_BUFLEN];
int iResult;
int recvbuflen = DEFAULT_BUFLEN;
// Validate the parameters
if (argc != 2) {
printf("usage: %s server-name\n", argv[0]);
return 1;
}
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed with error: %d\n", iResult);
return 1;
}
ZeroMemory( &hints, sizeof(hints) );
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
// Resolve the server address and port
iResult = getaddrinfo(argv[1], DEFAULT_PORT, &hints, &result);
if ( iResult != 0 ) {
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
return 1;
}
// Attempt to connect to an address until one succeeds
for(ptr=result; ptr != NULL ;ptr=ptr->ai_next) {
// Create a SOCKET for connecting to server
ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype,
ptr->ai_protocol);
if (ConnectSocket == INVALID_SOCKET) {
printf("socket failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
// Connect to server.
iResult = connect( ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
if (iResult == SOCKET_ERROR) {
closesocket(ConnectSocket);
ConnectSocket = INVALID_SOCKET;
continue;
}
break;
}
freeaddrinfo(result);
if (ConnectSocket == INVALID_SOCKET) {
printf("Unable to connect to server!\n");
WSACleanup();
return 1;
}
// Send an initial buffer
iResult = send( ConnectSocket, sendbuf, (int)strlen(sendbuf), 0 );
if (iResult == SOCKET_ERROR) {
printf("send failed with error: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
printf("Bytes Sent: %ld\n", iResult);
// shutdown the connection since no more data will be sent
iResult = shutdown(ConnectSocket, SD_SEND);
if (iResult == SOCKET_ERROR) {
printf("shutdown failed with error: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
// Receive until the peer closes the connection
do {
iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
if ( iResult > 0 )
printf("Bytes received: %d\n", iResult);
else if ( iResult == 0 )
printf("Connection closed\n");
else
printf("recv failed with error: %d\n", WSAGetLastError());
} while( iResult > 0 );
// cleanup
closesocket(ConnectSocket);
WSACleanup();
return 0;
}
the "send()" method is used.
Does it implicitly send an EOF (a CR LF sequence for example) to the server socket at the end of the message passed as an argument?
Is it documented somewhere?
Is it part of the socket implementation?
Note that, I am not adding a EOF (CR LF for example) at the end of the message.
I'm ending the message with a trailing '\0' character.
When a "message" (an array of characters) is sent from a socket endpoint to another socket endpoint, does the message have to be ended with some kind of EOF? It appears to me now that it doesn't.
There is no general need to send an EOF sign in java socket communication, BUT
if your client uses InputStream.readLine() to read the servers answer, than this is normal, because
readLine() blocks until a line has been completely read (until \n \r or \r\n found) or the socket is closed by the server.
But in this example, the socket is not closed by the server, because the server is waiting for the clients answer and if the client is waiting for the end of line, you have a deadlock.
when the server sends its response to the client socket, it writes to the "PrintWriter" "out" using the "println()" method
PrintWriter is line buffered. See the Javadoc.
I have tried using the "print()" method instead.
If you don't write a line it won't flush. Call flush() afterwards. But you shouldn't use PrintWriter over a network, as it swallows exceptions you need to know about. Use BufferedWriter.
In the "println()" case, the client socket receives the message properly.
Because it's line-buffered, so there was an auto-flush.
In the "print()" case, the client socket doesn't receive anything.
Because it's line-buffered so there wasn't an auto-flush.
Is this normal?
Yes.
Is it required to send an EOF, a CR LF (in my case) (10 and 13 ASCII characters) at the end of the message?
No.
Is it documented somewhere?
Yes, in the Javadoc for PrintWriter.
Initially I would like to thank you for your time...
I created a server socket in c++ in my macbook and a client/socket using Java in a diffrent machine which runs windows xp. I have specified the port to 5000 but I cant specify the correct Host and thus I can not make the connection. When I created a c++ server/socket in windows xp using WinSock2 the connection was made perfectly as I used the localhost...any ideas???
Thnx in advance
C++ code
int main( int argc, const char** argv )
{
/* SOCKET VARIABLES */
int sock;
struct sockaddr_in server;
int mysock;
char buff[1024];
int rval;
/*CREATE SOCKET*/
sock =socket(AF_INET, SOCK_STREAM, 0);
if (sock<0)
{
perror("*FAILED TO CREATE SOCKET*");
exit(1);
}
server.sin_family=AF_INET;
server.sin_addr.s_addr=INADDR_ANY;
server.sin_port=5000;
/*CALL BIND*/
if (bind(sock, (struct sockaddr *)&server, sizeof(server)))
{
perror("BIND FAILED");
exit(1);
}
/*LISTEN*/
listen(sock, 5);
/*ACCEPT*/
do{
mysock= accept(sock, (struct sockaddr *) 0, 0);
if (mysock==-1)
{
perror ("ACCEPT FAILED");
}
else
{
memset(buff, 0, sizeof(buff));
if ((rval=recv(mysock, buff, sizeof(buff), 0)) <0) {
perror("READING STREAM MESSAGE ERROR");
}
else if(rval==0)
printf("Ending connection");
else
printf("MSG: %s\n", buff);
printf("GOT THE MESSAGE (rval = %d)\n", rval);
}
return 0;
}while (1) ;
Java code
import java.io.;
import java.net.;
public class SOK_1_CLIENT {
public void run() throws Exception
{
Socket SOCK =new Socket ("localhost",5000);
PrintStream PS =new PrintStream(SOCK.getOutputStream());
PS.println("HELLO TO SERVER FROM CLIENT");
InputStreamReader IR =new InputStreamReader(SOCK.getInputStream());
BufferedReader BR = new BufferedReader(IR);
String MESSAGE =BR.readLine();
System.out.println(MESSAGE + "java");
}
}
In java client, use the IP address of the system which is running server not "localhost". Localhost will refer to the local loopback address of the machine running the client code which is 127.0.0.1, but you have your server running on different machine, hence connection is not possible:
public void run() throws Exception
{
String address = "address_of_machine_running_server";
Socket SOCK =new Socket (address,5000);
PrintStream PS =new PrintStream(SOCK.getOutputStream());
PS.println("HELLO TO SERVER FROM CLIENT");
InputStreamReader IR =new InputStreamReader(SOCK.getInputStream());
BufferedReader BR = new BufferedReader(IR);
String MESSAGE =BR.readLine();
System.out.println(MESSAGE + "java");
}
Also note that you need to set the firewall accordingly to allow the connections.
allow incoming and outgoing connections in both machine
check if ip address of your server is correct
try pinging the host(server) with its ip address to make sure that its up and working
if all the above returns positive, you will a have sucessfull connection.
I have two apps, one written in Java that sends string, it looks like this:
import java.io.*;
import java.net.*;
public class Gniazdo{
public static void main(String[] args) throws IOException {
DataOutputStream dataOutputStream = null;
Socket socket = null;
String mes = "Test message";
try {
socket = new Socket("192.168.1.116", 4014);
dataOutputStream = new DataOutputStream(socket.getOutputStream());
dataOutputStream.writeChars(mes);
} catch (UnknownHostException e) {
System.err.print(e);
} finally {
if(socket != null) {
socket.close();
}
if(dataOutputStream != null) {
dataOutputStream.close();
}
}
}
}
and second one is written in C and runs on Raspberry Pi, that should receive string :
#include <sys/socket.h>
#include <stdio.h>
#include <netinet/in.h>
#include <string.h>
int main(void) {
unsigned int port;
char bufor[1024];
int gniazdo, gniazdo2;
struct sockaddr_in adr, nadawca;
socklen_t dl;
printf("Enter port to listen : ");
scanf("%u", &port);
gniazdo = socket(AF_INET, SOCK_STREAM, 0);
adr.sin_family = AF_INET;
adr.sin_port = htons(port);
adr.sin_addr.s_addr = INADDR_ANY;
if (bind(gniazdo, (struct sockaddr*) &adr,
sizeof(adr)) < 0) {
printf("Bind failed.\n");
return 1;
}
if (listen(gniazdo, 10) < 0) {
printf("Listen failed.\n");
return 1;
}
printf("Waiting for connection ...\n");
while (gniazdo2 = accept(gniazdo,
(struct sockaddr*) &nadawca,
&dl)
)
{
// memset(bufor, 0, 1024);
recv(gniazdo2, bufor, 1024, 0);
printf("message from %s: %s\n", inet_ntoa(nadawca.sin_addr), bufor);
close(gniazdo2);
}
close(gniazdo);
}
and my output is:
Enter port to listen : 4014
Waiting for connection ...
message from 192.168.1.103:
message from 192.168.1.103:
message from 192.168.1.103:
message from 192.168.1.103:
Please could anyone tell me whats wrong?
Why i don't receive the message?
I even checked packets outgoing from my computer with Wireshark and they contains my message, but still don't know where I made mistake
1) Try calling writeBytes(String s) on the DataOutputStream.
2) Try calling flush on the DataOutputStream
(even though close should be calling flush anyway).
3) Try using PrintWriter to send the String
See
http://docs.oracle.com/javase/6/docs/api/java/io/PrintWriter.html#PrintWriter%28java.io.OutputStream,%20boolean%29
and this method in particular
http://docs.oracle.com/javase/6/docs/api/java/io/PrintWriter.html#write%28java.lang.String%29
4) Also, I think you should swap these two
if(socket != null) {
socket.close();
}
if(dataOutputStream != null) {
dataOutputStream.close();
}
printf is looking at 'bufor' as a char (8-bit), but java will write 16-bit UTF-16 characters. The first byte of the first character is 0. printf sees the 0 and thinks it's the end of the string. Try formatting the string to UTF-8 when you write it to the socket or reading it and printing it as a wchar.
I am trying to "Write a Java program that is a TCP server that returns a HTTP response to a browser that displays the client’s IP address and the number of times it has connected to the server"
Currently what I think is happening. I am creating a server and listening to the port (input as a argument) for a request, then filling a byte array and converting that array to a string. I wish then to just see the request at this point.
My problem is if I do try to connect to this server by going to my web-browser and typing "localhost:1235" my browser just keeps saying "connecting to ..." and my program does nothing it just sits and waits.
How might I go about fixing/and implemented the rest of this? What could my current problem be?
So far here is my code
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class TCPHTTP
{
private static final int MAXFILELEN = 4096000;
static byte[] request = new byte[MAXFILELEN];
static String[] log;
public static void main (String args[])
{
if (args.length != 1)
throw new IllegalArgumentException( "Parameter(s): <Port>");
int port = Integer.parseInt(args[0]);
ServerSocket socket = null;
Socket sock = null;
try
{
socket = new ServerSocket(port);
}
catch (IOException e)
{
return;
}
for (;;)
{
try
{
sock = socket.accept();
InputStream is = sock.getInputStream();
int offset = 0;
int len = 0;
while ((len = is.read(request, offset, MAXFILELEN - offset)) >= 0)
{
offset += len;
}
String s = new String(request);
System.out.println(s);
// Add the users IP to the log
String from = "From: ";
int loglen = log.length;
int indexOfSenderIP = s.indexOf(from, 0);
indexOfSenderIP += from.length();
int indexOfNewline = s.indexOf("\n", indexOfSenderIP);
String sendersIP = s.substring(indexOfSenderIP, indexOfNewline);
log[loglen] = sendersIP;
//Find out how many times the sender IP appears in the log
int timesVisited = 0;
for(int i = 0; i < log.length; i++)
if(log[i].endsWith(sendersIP))
timesVisited++;
// Construct the HTTP response message
String httpResponse = "";
OutputStream os = sock.getOutputStream();
os.write(httpResponse.getBytes());
os.close();
is.close();
sock.close();
}
catch (IOException e)
{
break;
}
}
}
}
Consider adding a Content-Length header to specify the size of your response so the browser knows how much to read.
the reason why your program freezes is that it waits for the client to close connection (read returns a value that's <0 after an eof).
you should read until you receive a double [cr][lf] from the client, that's what marks the ending of the http header
String httpResponse = "";
That's not a valid HTTP response. Your browser is waiting for a proper response. Send one.
from what i see, you closed the socket before answering the client's request
also, i tested your code, and that while cycle never ends