I am creating a simple game which consists of Java client and C server. When client sends first request to server, it is ok. The server sends response and client reads it. But when client send second request, the server sends response like always but client reads nothing. When I delete \n from response, clinet is stuck on readLine() which is ok, but when I place \n back, readLine() reads nothing. I am pretty desperate and I tryied variety of actions and changed the message from server like 1000 times but nothing works.
Here is connection method:
public int connect() {
try {
if (port != 0 && !host.equals(null)) {
socket = new Socket(host, port);
socket.setSoTimeout(5000);
socket.setKeepAlive(true);
} else {
socket = new Socket("localhost", 50001);
}
out = new OutputStreamWriter(socket.getOutputStream());
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
} catch (UnknownHostException ex1) {
System.out.println("Unknown host: " + host);
return 1;
} catch (IOException ex2) {
System.out.println("No I/O: " + ex2.getMessage());
return 2;
}
return 0;
}
Here are methods for comunication:
public String listRooms() throws DisconnectedException, IOException {
this.send(LIST_ROOMS);
String data = this.receive();
System.out.println("Action: " + LIST_ROOMS + " Result: " + data);
return data;
}
public int createRoom(String playerName) throws IOException, DisconnectedException {
this.send(playerName, CREATE_ROOM);
int result = this.receiveInt();
System.out.println("Action: " + CREATE_ROOM + " Result: " + result);
return result;
}
public void joinRoom(String playerName, int number) throws IOException, DisconnectedException {
String message = number + "\0" + playerName;
this.send(message, JOIN_ROOM);
try {
System.out.println("Action: " + JOIN_ROOM + " Result: " + this.receive());
} catch (SocketTimeoutException e) {
throw new DisconnectedException("Connection with server lost...");
}
}
private void send(String message, int actionNumber) throws IOException {
out.write((char) actionNumber);
out.write(message);
out.flush();
}
private void send(int actionNumber) throws IOException {
out.write((char) actionNumber);
out.flush();
}
private int receiveInt() throws IOException {
int response = in.read();
System.out.println(response);
return 0;
}
private String receive() throws IOException {
String answer = in.readLine();
System.out.println("ANSWER: " + answer);
if (answer == null) {
System.out.println("You recieved nothing Jon Snow...");
} else if ("0".equals(answer)) {
System.out.println("Error recieveing answer from server");
return "0";
}
return answer;
}
and here is server:
#include <arpa/inet.h>
#include <netinet/in.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#include "room.h"
void error_message(const char *msg);
typedef struct thread_args
{
int client_sock;
char ip_address[16];
} thread_args;
void *thread_service(void *args)
{
int client_sock;
char buffer[256] = "";
char cbuf;
int n;
char address[16] = "";
int result = 0;
room *room = NULL;
client_sock = ((thread_args *) args)->client_sock;
strcpy(address, ((thread_args *) args)->ip_address);
pthread_detach(pthread_self());
while(1)
{
if ((recv(client_sock, &cbuf, 1, 0)) == -1)
{
printf("Receive message from %s failure\n", address);
break;
}
switch (cbuf) {
case 0:
result = create_room(&room, client_sock);
if(!result)
{
/* TODO */
}
memset(buffer, 0, 256);
sprintf(buffer, "%d\n", result);
n = send(client_sock, buffer, 256, 0);
if (n <= 0) {
perror("ERROR writing to socket\n");
close(client_sock);
break;
}
printf("sent\n");
break;
case 1:
result = join_room(&room, client_sock);
if(!result)
{
/* TODO */
}
printf("Join to room for %s\n", address);
sprintf(buffer, "%d\n", result);
n = send(client_sock, buffer, 256, 0);
if (n <= 0) {
perror("ERROR writing to socket\n");
break;
}
break;
case 2:
printf("List rooms\n");
memset(buffer, 0, 256);
result = list_rooms(buffer);
if(!result) {
/* TODO */
}
printf("Sending message: %s", buffer);
n = send(client_sock, buffer, 256, 0);
if (n <= 0) {
perror("ERROR writing to socket\n");
close(client_sock);
break;
}
printf("Sent\n");
break;
case 5:
exit(0);
break;
}
}
close(client_sock);
free(args);
return 0;
}
int main(int argc, char *argv[])
{
int sock_fd = 0, new_sock_fd = 0, port = 0, clilen = 0;
struct sockaddr_in serv_addr, cli_addr;
int *th_socket;
pthread_t thread_id;
thread_args *args = (thread_args *)malloc(sizeof(thread_args));
char address[16];
int yes = 1;
if(argc < 2)
{
fprintf(stderr, "Error missing port");
return 0;
}
sock_fd = socket(AF_INET, SOCK_STREAM, 0);
if(sock_fd < 0)
fprintf(stderr, "Error opening socket");
memset(&serv_addr, 0, sizeof(serv_addr));
port = atoi(argv[1]);
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(port);
serv_addr.sin_addr.s_addr = INADDR_ANY;
if (setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == 0)
{
printf("Socket options was set.\n"); //TODO
}
else
{
printf("Set socket options failure.\n"); //TODO
}
if(bind(sock_fd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
error_message("Error in connection");
listen(sock_fd, 5);
if (pthread_mutex_init(&lock, NULL) != 0)
{
printf("Mutex init failed.\n");
return 1;
}
while(1)
{
printf("Waiting for new connection\n");
clilen = sizeof(cli_addr);
new_sock_fd = accept(sock_fd, (struct sockaddr *)&cli_addr, &clilen);
if (new_sock_fd < 0) {
printf("Error accepting new connection!\n");
continue;
}
strcpy(args->ip_address, inet_ntoa(cli_addr.sin_addr));
args->client_sock = new_sock_fd;
if (new_sock_fd > 0 ) {
th_socket=malloc(sizeof(int));
*th_socket=new_sock_fd;
printf("Creating new thread for %s\n", args->ip_address);
pthread_create(&thread_id, NULL, (void *)&thread_service, (void *)args);
} else {
printf("Error creating thread for new connection.\n");
return -1;
}
}
return 0;
}
So if you want to send C servera message, it will look like this:
String message = "Hello world!";
OutputStreamWriter out = new OutputStreamWriter(socket.getOutputStream());
out.write(message + "\n");
out.flush();
UPDATE: A have figured that out, it was pretty nasty fault, maybe it would help others.. In message from JAVA client to server must be (in my case) manually appended "\n" character, otherwise it sends some characters that will confuse the server. so my code looks like this out.write(message + "\n"); and then just call flush() and it will be ok.
You have to add the enline character, but if you had use the printWriter instead then you could use the println method...
PrintWriter pw = new PrintWriter(socket.getOutputStream(), true);
pw.println("Bla bla");
So the answer is simple. If you are using OutputStreamWritter you have to add newline character to your message.
Related
I have a C client which uses UDP to send packets to my PC's IP address. Below is the function used to initialize the socket:
void log_init(const char *ipString) {
log_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (log_socket < 0)
return;
struct sockaddr_in connect_addr;
memset(&connect_addr, 0, sizeof(connect_addr));
connect_addr.sin_family = AF_INET;
connect_addr.sin_port = 4405;
inet_aton(ipString, &connect_addr.sin_addr);
if (connect(log_socket, (struct sockaddr *) &connect_addr, sizeof(connect_addr)) < 0) {
socketclose(log_socket);
log_socket = -1;
}
}
Here is the sending code:
void log_print(const char *str) {
// socket is always 0 initially as it is in the BSS
if (log_socket < 0) {
return;
}
int len = strlen(str);
int ret;
while (len > 0) {
int block = len < 1400 ? len : 1400; // take max 1400 bytes per UDP packet
ret = send(log_socket, str, block, 0);
if (ret < 0)
break;
len -= ret;
str += ret;
}
}
In Java, I want to receive those messages but they never arrive, it's always stuck on receive():
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class UDPServer
{
public static void main(String[] arguments) throws Exception
{
System.out.println("Binding...");
DatagramSocket serverSocket = new DatagramSocket(4405);
System.out.println("Binded!");
byte[] receiveData = new byte[1400];
while (true)
{
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
System.out.println("Receiving...");
serverSocket.receive(receivePacket);
String sentence = new String(receivePacket.getData());
System.out.println("Received: " + sentence);
}
}
}
Interestingly, a C server on the same machine as the Java server works just fine and indeed receives the messages. The socket initialization and receive functions are below:
int NetInit()
{
if(sock_id >= 0)
return sock_id;
#ifdef WIN32
WSADATA wsaData;
// Initialize Winsock
if (WSAStartup(MAKEWORD(2,2), &wsaData) == SOCKET_ERROR)
return -1;
#endif
//Get a socket
if((sock_id = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP)) == -1)
return -1;
#ifdef WIN32
u_long mode = 1;
ioctlsocket(sock_id, FIONBIO, &mode);
#else
int flags = fcntl(sock_id, F_GETFL, 0);
fcntl(sock_id, F_SETFL, flags | O_NONBLOCK);
#endif
return sock_id;
}
int NetRead(void *buffer, unsigned int buf_len)
{
if(sock_id < 0)
return sock_id;
fd_set fdsRead;
FD_ZERO(&fdsRead);
FD_SET(sock_id, &fdsRead);
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 10000;
if(select(sock_id + 1, &fdsRead, NULL, NULL, &tv) != 1) {
return 0;
}
int len = sizeof(servaddr);
return recvfrom(sock_id,buffer, buf_len, 0,(struct sockaddr *)&servaddr, &len);
}
How do I get receiving messages to work with Java?
I'm trying to modify a client-server program so that I can connect to the server(which I run in VirtualBox on Linux) which is written in C, from a client which I want to run in Windows, and is written in Java.
I have a few problems though. Here is my server.c file which I run on Linux:
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <string.h>
void deservire_client(int c) {
// serving the client
int nr, i=2, nrDiv=0, sirDiv[10]={0,0,0,0,0,0,0,0,0,0};
recv(c, &nr, sizeof(nr), MSG_WAITALL);
while ( i <= nr/2){
if ( nr%i == 0){
sirDiv[nrDiv]=i;
nrDiv+=1;
}
i+=1;
}
send(c, &sirDiv, sizeof(sirDiv), 0);
close(c);
// ending of serving the client;
}
int main() {
int s;
struct sockaddr_in server, client;
int c, l;
s = socket(AF_INET, SOCK_STREAM, 0);
if (s < 0) {
printf("Creating server socket error!\n");
return 1;
}
memset(&server, 0, sizeof(server));
server.sin_port = htons(1234);
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
if (bind(s, (struct sockaddr *) &server, sizeof(server)) < 0) {
printf("Binding Error!\n");
return 1;
}
listen(s, 5);
l = sizeof(client);
memset(&client, 0, sizeof(client));
while (1) {
c = accept(s, (struct sockaddr *) &client, &l);
printf("S-a conectat un client.\n");
if (fork() == 0) { // fiu
deservire_client(c);
return 0;
}
}
}
As you can see, the server will return an array of integers, which will be the divisors of the number I send in from the client file.
I have written a client file, also in C, just to see if it works. I run them both under Linux though. Here's the file:
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <string.h>
#include <unistd.h>
int main() {
int c;
struct sockaddr_in server;
char send_data[1024];
c = socket(AF_INET, SOCK_STREAM, 0);
if (c < 0) {
printf("Creating client socket error!\n");
return 1;
}
memset(&server, 0, sizeof(server));
server.sin_port = htons(1234);
server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr("127.0.0.1");
if (connect(c, (struct sockaddr *) &server, sizeof(server)) < 0) {
printf("Connecting to server error!\n");
return 1;
}
while(1){
int nr, sirDiv[10]={0,0,0,0,0,0,0,0,0,0}, i=0;
printf("\nInput number: "); scanf("%d",&nr);
send(c ,&nr, sizeof(nr), 0);
recv(c, &sirDiv, sizeof(sirDiv), 0);
printf("\nThe divisors are:\n");
while( i <= 10 ){
if ( sirDiv[i] <= nr/2 && sirDiv[i] != 0)
printf("%d ",sirDiv[i]);
i+=1;
}
printf("\n");
//Ask client if he wants to close
printf("\nq or Q to exit: ");
scanf("%s",send_data);
if (strcmp(send_data , "q") == 0 || strcmp(send_data , "Q") == 0) {
close(c);
break;
}
}
return 0;
}
So this works fine under Linux, and I can connect multiple clients to the server. Now I want to create a client and write it in Java. Here's an example that has been given to me and that I'm trying to modify:
import java.net.*;
import java.io.*;
public class Client2 {
private static final String SERVER_ADDRESS = "127.0.0.1";
private static final int SERVER_PORT = 1234;
private static final int UNSIGNED_SHORT_MAX_VALUE = 65535;
private static final int UNSIGNED_SHORT_MIN_VALUE = 0;
public static void main(String args[]) {
Socket socket = null;
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(System.in));
socket = new Socket(SERVER_ADDRESS, SERVER_PORT);
int a = readUnsignedShort("a = ", reader);
int b = readUnsignedShort("b = ", reader);
writeIntegersToSocket(a, b, socket);
readIntegersSumFromSocket(socket);
} catch (IOException e) {
System.err.println("Cautgh exception " + e.getMessage());
} finally {
closeStreams(socket,reader);
}
}
private static void readIntegersSumFromSocket(Socket c) throws IOException {
DataInputStream socketIn = new DataInputStream(c.getInputStream());
int s = socketIn.readUnsignedShort();
System.out.println("s = " + s);
}
private static void writeIntegersToSocket(int a, int b, Socket c) throws IOException {
DataOutputStream socketOut = new DataOutputStream(c.getOutputStream());
socketOut.writeShort(a);
socketOut.writeShort(b);
socketOut.flush();
}
private static int readUnsignedShort(String message, BufferedReader reader) throws IOException {
int unsignedShortNumber = 0;
System.out.print(message);
try {
unsignedShortNumber = Integer.parseInt(reader.readLine());
if (unsignedShortNumber < UNSIGNED_SHORT_MIN_VALUE || unsignedShortNumber > UNSIGNED_SHORT_MAX_VALUE) {
throw new IllegalArgumentException("The given number must be unsigned short [0..65535]!");
}
} catch (NumberFormatException e) {
System.err.println("The given input is not an integer!");
}
return unsignedShortNumber;
}
private static void closeStreams(Socket socket, BufferedReader reader) {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
System.err.println("Could not close socket!");
}
}
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
System.err.println("Could not close reader!");
}
}
}
}
This example was made for a client-server program which lets the user input two numbers, and the server will return the sum. I have a few problems when I'm trying to modify it though.
public static void main(String args[]) {
Socket socket = null;
int i = 0;
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(System.in));
socket = new Socket(SERVER_ADDRESS, SERVER_PORT);
int nr = readUnsignedShort("nr = ", reader);
while(int i <=10)
int sirDiv[i] = readUnsignedShort("b = ", reader);//Here I have an error, type mismatch, how do I fix this?
writeIntegersToSocket(nr, sirDiv, socket);//Again, how do I write this instead?
readIntegersSumFromSocket(socket);
private static void writeIntegersToSocket(int a, int b, Socket c) throws IOException {
DataOutputStream socketOut = new DataOutputStream(c.getOutputStream());
socketOut.writeShort(nr);
socketOut.writeShort(nrDiv); //will probably have an error here as well
socketOut.flush();
}
Apart from these type mismatches, I still don't know how to connect to the server which I run on linux as in, what do I have to change, the SERVER_ADDRESS or something? Pinging localhost in Linux gives me 127.0.0.1 and pinging 'ping -4 localhost' in Windows gives me the same thing. Could anyone give me a few pointers with this? I've been trying all day.
This question already exists:
client not reading the first message from the server [closed]
Closed 9 years ago.
First, here is my server. Please look at this part
if(clients.size() == 2){
sendStartSignal();
break;
}
In the above part, i send a start signal "start" string when at least two clients connect to the server.
Server code begins here....
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <iostream>
#include <pthread.h>
#include <vector>
#include <sys/fcntl.h>
using namespace std;
void * handle_client(void * ptr);
void sendStartSignal();
struct thdata{
int client_no;
};
vector<pthread_t *> clients;
vector<int> client_nos;
int main(int argc, char **argv)
{
struct sockaddr_in server_addr,client_addr;
socklen_t clientlen = sizeof(client_addr);
int option, port, reuse;
int server, client;
int nread;
// setup default arguments
port = 3000;
// process command line options using getopt()
// see "man 3 getopt"
while ((option = getopt(argc,argv,"p:")) != -1) {
switch (option) {
case 'p':
port = atoi(optarg);
break;
default:
cout << "server [-p port]" << endl;
exit(EXIT_FAILURE);
}
}
// setup socket address structure
memset(&server_addr,0,sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
server_addr.sin_addr.s_addr = INADDR_ANY;
// create socket
server = socket(PF_INET,SOCK_STREAM,0);
if (!server) {
perror("socket");
exit(-1);
}
// set socket to immediately reuse port when the application closes
reuse = 1;
if (setsockopt(server, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0) {
perror("setsockopt");
exit(-1);
}
// call bind to associate the socket with our local address and
// port
if (bind(server,(const struct sockaddr *)&server_addr,sizeof(server_addr)) < 0) {
perror("bind");
exit(-1);
}
// convert the socket to listen for incoming connections
if (listen(server,SOMAXCONN) < 0) {
perror("listen");
exit(-1);
}
// accept clients
while ((client = accept(server,(struct sockaddr *)&client_addr,&clientlen)) > 0) {
//make the clients non blocking
fcntl(client, F_SETFL, O_NONBLOCK);
pthread_t* th = new pthread_t;
thdata* data = new thdata;
data->client_no = client;
clients.push_back(th);
client_nos.push_back(client);
pthread_create(th, NULL, &handle_client, (void *) data);
if(clients.size() == 2){
sendStartSignal();
break;
}
}
for(int i=0;i<clients.size();i++){
pthread_join(*clients[i], NULL);
}
}
void sendStartSignal(){
char *buf;
int buflen;
int nread;
// allocate buffer
buflen = 1024;
buf = new char[buflen+1];
buf[0] = 's';
buf[1] = 't';
buf[2] = 'a';
buf[3] = 'r';
buf[4] = 't';
buf[5] = 0;
for(int i = 0;i<clients.size();i++) {
send(client_nos[i], buf, 6, 0);
}
}
void * handle_client(void * ptr){
thdata * data = (thdata*) ptr;
char *buf;
int buflen;
int nread;
// allocate buffer
buflen = 1024;
buf = new char[buflen+1];
int client_no = data->client_no;
// loop to handle all requests
while (1) {
// read a request
memset(buf,0,buflen);
nread = recv(client_no,buf,buflen,0);
if(nread >= 0){
if(nread == 0) {
int index_to_delete = -1;
for(int i=0;i<client_nos.size();i++){
if(client_nos[i] == client_no){
index_to_delete = 0;
break;
}
}
clients.erase(clients.begin() + index_to_delete);
client_nos.erase(client_nos.begin() + index_to_delete);
break;
}
for(int i = 0;i<clients.size();i++) {
if (client_nos[i] != client_no){
send(client_nos[i], buf, nread, 0);
}
}
}
}
}
Now, here is my client in java
Please look at this part...
public static void handle_read(){
while(true){
try{
String line = r.readLine();
System.out.println(line);
}
catch(Exception e){
System.err.println(e);
}
}
}
In the above part, it is a thread that just reads incoming message from the server. Now, my question is, as you can see in server code that as soon as two connections are made, "start" signal is sent to the clients....now, the client doesnt print start as soon as two clients connect to the server...it only prints "start" after i send some message to the server. Why is this so?
Client starts here ....
import java.io.*;
import java.net.*;
import java.util.*;
public class Client
{
public static BufferedReader r;
public static PrintWriter w;
public static void main(String[] args){
try
{
Socket s = new Socket("localhost", 3000);
r = new BufferedReader(new InputStreamReader(s.getInputStream()));
w = new PrintWriter(s.getOutputStream(), true);
BufferedReader con = new BufferedReader(new InputStreamReader(System.in));
Thread t1 = new Thread(){
public void run(){
handle_read();
}
};
Thread t2 = new Thread(){
public void run(){
handle_write();
}
};
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println("Exiting .... ");
}
catch (Exception err)
{
System.err.println(err);
}
}
public static void handle_read(){
while(true){
try{
String line = r.readLine();
System.out.println(line);
}
catch(Exception e){
System.err.println(e);
}
}
}
public static void handle_write(){
while(true){
try{
Scanner scan = new Scanner(System.in);
String s = scan.next();
w.println(s);
}
catch(Exception e){
System.err.println(e);
}
}
}
}
Thank you!
You are sending this message:
buf[0] = 's';
buf[1] = 't';
buf[2] = 'a';
buf[3] = 'r';
buf[4] = 't';
buf[5] = 0;
Then you are reading it with this code
String line = r.readLine();
This seems like a mismatch. You are not sending a line, but you are trying to read a line.
End the message you send with a newline character, '\n'
I have a TCP server that is written in Java, and a client that is written in C.
I am sending array of chars from the client, but the only thing that is received in the server is a blank line, there aren’t any characters.
Do you know why is this happening and how can I solve this problem? How can I encode the message in the server part?
Maybe the problem is in decoding? I know that in C programming language char is byte, and I know in Java it is 2 bytes.
The part of the server that is written in Java is :
public class main {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
TCPServerHandler handler; // Креирање на handler за TCP серверот
handler = new TCPServerHandler() {
//Доколку сакате да го опширите onConnect
#Override
public boolean onConnect(INonBlockingConnection inbc) throws IOException, BufferUnderflowException, MaxReadSizeExceededException {
super.onConnect(inbc); //Задолжително повикување на super.onConnect(inbc)
//Доколку сакате да го дополните onConnect
System.out.println("Connected:"+inbc.getRemoteAddress().getHostAddress()+":"+inbc.getRemotePort());
return true;
}
//Доколку сакате да го опширите onDisconnect
#Override
public boolean onDisconnect(INonBlockingConnection inbc) throws IOException {
super.onDisconnect(inbc); //Задолжително повикување на super.onDisconnect(inbc)
//Доколку сакате да го дополните onDisconnect
System.out.println("Discconected:"+inbc.getRemoteAddress().getHostAddress()+":"+inbc.getRemotePort());
return true;
}
#Override
public boolean onData(INonBlockingConnection inbc) throws IOException, BufferUnderflowException, ClosedChannelException, MaxReadSizeExceededException {
String data = this.readString(inbc);
int sizeofdata = data.length();
System.out.println(sizeofdata);
//Што понатака зависи од самата апликација
System.out.println(data);
// this.writeString(inbc, "OK");
return true;
}
};
TCPServer server = new TCPServer(9912, handler); // Иницијализирање на серверот на порта 9001 со handler
server.start(); //Започнување на серверот
try {
while (true) {
if (server.getServerStatus() == true) { //Проверка дали започнал
System.out.println("Server started");
break;
}
}
while (true) {
//Што и да ќе правте откако ќе започне серверот
}
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
So, here I am reading like string, and maybe that is the problem.
The client part written in c is:
static unsigned int barcode[17];
void PRINT_BARCODE_ONLY(void)
{
int i;
for (i = 0; i < 16; i++)
{
barcode[i] = rx_buffer[6 + i] - 0x30;
}
barcode[16] = 35;
printf("%c[1;31mBARCODE: ", 27);
for (i = 0; i < 16; i++)
{
printf("%X", barcode[i]);
}
}
int SEND_BARCODE_TCP(void)
{
int sock_descriptor;
struct sockaddr_in serv_addr;
struct hostent *server;
sock_descriptor = socket(AF_INET, SOCK_STREAM, 0);
if (sock_descriptor < 0)
printf("Failed creating socket\n");
bzero((char *) &serv_addr, sizeof(serv_addr));
//server = gethostbyname("10.10.1.120");
server = gethostbyname("192.168.123.103");
//server = gethostbyname("127.0.0.1");
if (server == NULL)
{
printf("Failed finding server name\n");
return -1;
}
serv_addr.sin_family = AF_INET;
memcpy((char *) &(serv_addr.sin_addr.s_addr), (char *) (server->h_addr),
server->h_length);
serv_addr.sin_port = htons(9912);
//serv_addr.sin_port = htons(1234);
if (connect(sock_descriptor, (struct sockaddr *) &serv_addr,
sizeof(serv_addr)) < 0)
{
printf("Failed to connect to server\n");
return -1;
}
else
printf("Connected successfully \n");
int count = write(sock_descriptor, barcode, sizeof(barcode));
if (count < 0)
printf("Failed writing rquested bytes to server\n");
close(sock_descriptor);
return 0;
}
TCP socket streams are byte based. This is why an encoding is used to convert chars to bytes when you read/write. It appears the main method readString() is missing, but I assume you have specified the enocding the C program is using or assumed the default encoding is ok.
When i use one jpeg image with this web-server its very slow to show the picture in the browser. But the same picture when i open using Apache web server its super fast.
What am i missing in my code which is so slow to render the jpeg file? Following is the code i am using:
server.java:
package www;
import java.io.*;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
public class server extends Thread
{
public server(int listen_port, webserver_starter to_send_message_to)
{
message_to = to_send_message_to;
port = listen_port;
this.start();
}
private void s(String s2)
{
message_to.send_message_to_window(s2);
}
private webserver_starter message_to;
private int port;
public void run()
{
ServerSocket serversocket = null;
s("The httpserver v. 0000000000\n\n");
try {
s("Trying to bind to localhost on port " + Integer.toString(port) + "...");
serversocket = new ServerSocket(port);
}catch (Exception e) {
s("\nFatal Error:" + e.getMessage());
System.exit(0);
return;
}
s("OK!\n");
while (true)
{
s("\nReady, Waiting for requests...\n");
try {
Socket connectionsocket = serversocket.accept();
InetAddress client = connectionsocket.getInetAddress();
s(client.getHostName() + " connected to server.\n");
BufferedReader input =
new BufferedReader(new InputStreamReader(connectionsocket.
getInputStream()));
DataOutputStream output =
new DataOutputStream(connectionsocket.getOutputStream());
http_handler(input, output);
} catch (Exception e) {
s("\nError:" + e.getMessage());
}
}
}
private void http_handler(BufferedReader input, DataOutputStream output)
{
int method = 0; //1 get, 2 head, 0 not supported
String http = new String(); //a bunch of strings to hold
String path = new String(); //the various things, what http v, what path,
String file = new String(); //what file
String user_agent = new String(); //what user_agent
try {
String tmp = input.readLine(); //read from the stream
String tmp2 = new String(tmp);
tmp.toUpperCase(); //convert it to uppercase
if (tmp.startsWith("GET")) { //compare it is it GET
method = 1;
} //if we set it to method 1
if (tmp.startsWith("HEAD")) { //same here is it HEAD
method = 2;
} //set method to 2
if (method == 0) {
try {
output.writeBytes(construct_http_header(501, 0));
output.close();
return;
}
catch (Exception e3) {
s("error:" + e3.getMessage());
}
}
int start = 0;
int end = 0;
for (int a = 0; a < tmp2.length(); a++) {
if (tmp2.charAt(a) == ' ' && start != 0) {
end = a;
break;
}
if (tmp2.charAt(a) == ' ' && start == 0) {
start = a;
}
}
path = tmp2.substring(start + 2, end);
}
catch (Exception e) {
s("errorr" + e.getMessage());
}
s("\nClient requested:" + new File(path).getAbsolutePath() + "\n");
FileInputStream requestedfile = null;
try {
requestedfile = new FileInputStream(path);
}
catch (Exception e) {
try {
output.writeBytes(construct_http_header(404, 0));
output.close();
}
catch (Exception e2) {}
;
s("error" + e.getMessage());
}
try {
int type_is = 0;
if (path.endsWith(".zip"))
{
type_is = 3;
}
if (path.endsWith(".jpg") || path.endsWith(".jpeg"))
{
type_is = 1;
}
if (path.endsWith(".gif"))
{
type_is = 2;
}
output.writeBytes(construct_http_header(200, 5));
if (method == 1)
{
while (true)
{
int b = requestedfile.read();
if (b == -1) {
break; //end of file
}
output.write(b);
}
}
output.close();
requestedfile.close();
}
catch (Exception e) {}
}
private String construct_http_header(int return_code, int file_type)
{
String s = "HTTP/1.0 ";
switch (return_code)
{
case 200:
s = s + "200 OK";
break;
case 400:
s = s + "400 Bad Request";
break;
case 403:
s = s + "403 Forbidden";
break;
case 404:
s = s + "404 Not Found";
break;
case 500:
s = s + "500 Internal Server Error";
break;
case 501:
s = s + "501 Not Implemented";
break;
}
s = s + "\r\n";
s = s + "Connection: close\r\n";
s = s + "Server: SimpleHTTPtutorial v0\r\n";
switch (file_type) {
case 0:
break;
case 1:
s = s + "Content-Type: image/jpeg\r\n";
break;
case 2:
s = s + "Content-Type: image/gif\r\n";
case 3:
s = s + "Content-Type: application/x-zip-compressed\r\n";
default:
//s = s + "Content-Type: text/html\r\n";
s = s + "Content-Type: image/jpeg\r\n";
break;
}
s = s + "\r\n";
return s;
}
}
Well here's the first thing I'd fix:
while (true)
{
int b = requestedfile.read();
if (b == -1) {
break; //end of file
}
output.write(b);
}
You're reading and writing a single byte at a time. That will be painfully slow. Read and write a whole buffer at a time instead:
byte[] buffer = new byte[32 * 1024]; // 32K is a reasonable buffer size
int bytesRead;
while ((bytesRead = requestedfile.read(buffer)) > 0) {
output.write(buffer, 0, bytesRead);
}
There may well be other performance problems in your code - there are certainly a lot of things I'd change about it, including following Java naming conventions everywhere and certainly fixing this:
// You should basically *never* have this code
catch (Exception e){}
... but as you asked about the performance, that's the first bit I've checked for.