在使用来自java客户端的executor服务时,c服务器未接收到数据
我有一个简单的c服务器和java客户端实现,我正在测试服务器的请求处理。我正在使用executor服务模拟同步请求 机制:服务器只是从客户端读取一个字符串,并通过向客户端发回消息来确认它 问题:对于某些请求,服务器无法获取客户端发送的消息 C服务器:在使用来自java客户端的executor服务时,c服务器未接收到数据,java,c,client-server,executorservice,Java,C,Client Server,Executorservice,我有一个简单的c服务器和java客户端实现,我正在测试服务器的请求处理。我正在使用executor服务模拟同步请求 机制:服务器只是从客户端读取一个字符串,并通过向客户端发回消息来确认它 问题:对于某些请求,服务器无法获取客户端发送的消息 C服务器: #include <stdio.h> #include <string.h> //strlen #include <stdlib.h> //strlen #include <sys/socket
#include <stdio.h>
#include <string.h> //strlen
#include <stdlib.h> //strlen
#include <sys/socket.h>
#include <arpa/inet.h> //inet_addr
#include <unistd.h> //write
#include <pthread.h> //for threading , link with lpthread
//the thread function
void *connection_handler(void *);
int main(int argc , char *argv[])
{
int socket_desc , client_sock , c;
struct sockaddr_in server , client;
static int client_count = 0;
//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( 5000 );
//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 , 1000);
//Accept and incoming connection
puts("Waiting for incoming connections...");
c = sizeof(struct sockaddr_in);
pthread_t thread_id;
while( (client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c)) )
{
client_count++;
printf("Connection accepted for client no : %d\n",client_count);
if( pthread_create( &thread_id , NULL , connection_handler , (void*) &client_sock) < 0)
{
perror("could not create thread");
return 1;
}
//Now join the thread , so that we dont terminate before the thread
//pthread_join( thread_id , NULL);
puts("Handler assigned");
}
if (client_sock < 0)
{
perror("accept failed");
return 1;
}
return 0;
}
void *connection_handler(void *socket_desc)
{
//Get the socket descriptor
int sock = *(int*)socket_desc;
int read_size, t = 0, operation = -1, buffer_size = 0;
char *message , recv_meta[2000], *data[3];
//Receive a message from client
while(read_size = recv(sock, recv_meta, 2000, 0) > 0 ) {
printf("Meta from client : %s\n",recv_meta);
sprintf(recv_meta, "%s", "OK, Meta Data received!");
send(sock, recv_meta, strlen(recv_meta), 0); //send acknowledgement
}
if(read_size == 0)
{
puts("Client disconnected");
fflush(stdout);
}
else if(read_size == -1)
{
perror("recv failed");
}
return 0;
}
#包括
#包括//strlen
#包括//strlen
#包括
#包括//inet\u addr
#包括//写入
#包括//对于线程,使用lpthread链接
//线程函数
void*连接处理程序(void*);
int main(int argc,char*argv[])
{
int socket_desc,client_sock,c;
服务器、客户端中的结构sockaddr_;
静态int客户端计数=0;
//创建套接字
socket\u desc=socket(AF\u INET,SOCK\u STREAM,0);
如果(套接字描述==-1)
{
printf(“无法创建套接字”);
}
放置(“已创建套接字”);
//在结构中准备sockaddr_
server.sinu family=AF\u INET;
server.sin\u addr.s\u addr=INADDR\u ANY;
server.sin_port=htons(5000);
//束缚
if(绑定(socket_desc,(struct sockaddr*)&server,sizeof(server))<0
{
//打印错误消息
perror(“绑定失败。错误”);
返回1;
}
看跌期权(“绑定完成”);
//听
听(插座描述,1000);
//接受和传入连接
puts(“等待传入连接…”);
c=sizeof(结构sockaddr_in);
pthread_t thread_id;
而((client_sock=accept(socket_desc,(struct sockaddr*)和client,(socklen_t*)和c)))
{
客户端计数++;
printf(“已接受客户端编号为%d\n的连接”,客户端计数);
if(pthread_create(&thread_id,NULL,connection_handler,(void*)和client_sock)<0)
{
perror(“无法创建线程”);
返回1;
}
//现在加入线程,这样我们就不会在线程之前终止
//pthread_join(thread_id,NULL);
看跌期权(“指定的处理人”);
}
如果(客户_sock<0)
{
perror(“接受失败”);
返回1;
}
返回0;
}
void*连接处理程序(void*套接字描述)
{
//获取套接字描述符
int sock=*(int*)插座描述;
int read_size,t=0,operation=-1,buffer_size=0;
char*消息,recv_meta[2000],*数据[3];
//从客户端接收消息
而(read_size=recv(sock,recv_meta,2000,0)>0){
printf(“来自客户端的元:%s\n”,recv_Meta);
sprintf(recv_meta,“%s”,“OK,元数据已收到!”);
发送(sock,recv_meta,strlen(recv_meta),0);//发送确认
}
如果(读取大小==0)
{
出售(“客户断开连接”);
fflush(stdout);
}
else if(读取大小==-1)
{
perror(“recv失败”);
}
返回0;
}
Java客户端:
import java.net.*;
import java.io.*;
import java.util.Arrays;
import java.util.concurrent.*;
public class client
{
public static void main(String[] args)
{
ExecutorService executorService = Executors.newFixedThreadPool(100);
for (int i = 0; i < 5; i++) {
Runnable worker = new WorkerThread(""+i);
executorService.execute(worker);
}
executorService.shutdown();
}
}
class WorkerThread implements Runnable {
String clientcount = "";
public WorkerThread(String s){
this. clientcount=s;
}
@Override
public void run() {
Socket socket = null;
int PORT = 5000, buffer_size = 0;
String meta = " ";
meta = "newfileidforenc:1:20000";
// Create the socket connection to the EchoServer.
try
{
socket = new Socket("localhost", PORT);
}
catch(UnknownHostException uhe)
{
// Host unreachable
System.out.println("Unknown Host");
}
catch(IOException ioe)
{
// Cannot connect to port on given host
System.out.println("Cant connect to server at port "+PORT+". Make sure it is running.");
return;
}
try
{
PrintWriter pout = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
BufferedReader pin = new BufferedReader(new InputStreamReader(socket.getInputStream()));
pout.println(meta);
pout.flush();
System.out.println("\nServer Says : " + pin.readLine() + "for "+ clientcount);
}
catch(Exception ioe)
{
System.out.println("\nException during communication. Server probably closed connection.");
}
finally
{
try
{
// Close the socket before quitting
socket.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
}
import java.net.*;
导入java.io.*;
导入java.util.array;
导入java.util.concurrent.*;
公共类客户端
{
公共静态void main(字符串[]args)
{
ExecutorService ExecutorService=Executors.newFixedThreadPool(100);
对于(int i=0;i<5;i++){
Runnable worker=新WorkerThread(“+i”);
executorService.execute(工人);
}
executorService.shutdown();
}
}
类WorkerThread实现Runnable{
字符串clientcount=“”;
公共WorkerThread(字符串s){
this.clientcount=s;
}
@凌驾
公开募捐{
套接字=空;
int端口=5000,缓冲区大小=0;
字符串meta=“”;
meta=“newfileidforenc:1:20000”;
//创建到EchoServer的套接字连接。
尝试
{
套接字=新套接字(“本地主机”,端口);
}
捕获(未知后异常uhe)
{
//无法访问主机
System.out.println(“未知主机”);
}
捕获(ioe异常ioe)
{
//无法连接到给定主机上的端口
System.out.println(“无法连接到端口“+端口+”处的服务器。请确保它正在运行。”);
回来
}
尝试
{
PrintWriter pout=新的PrintWriter(新的OutputStreamWriter(socket.getOutputStream());
BufferedReader引脚=新的BufferedReader(新的InputStreamReader(socket.getInputStream());
pout.println(meta);
撅嘴,脸红;
System.out.println(“\n服务器说:“+pin.readLine()+”表示“+clientcount”);
}
捕获(异常ioe)
{
System.out.println(“\n通信期间出现异常。服务器可能已关闭连接。”);
}
最后
{
尝试
{
//退出前关闭插座
socket.close();
}
捕获(例外e)
{
e、 printStackTrace();
}
}
}
}
输出:不一样。所有客户端成功连接并断开连接。但是服务器没有从所有客户端接收和打印数据。您在以下方面有很多问题: 1) 未正确处理TCP流,并假设TCP传输消息而不是八位字节(字节)流 2) 不理解将msaquerade作为字符串类型的以null结尾的C样式字符数组 3) 按地址传递值以创建线程调用
请参阅评论。我找到了解决该问题的方法 实际问题:Executor服务用于负载测试,即每秒发送的请求数会更多。在如此重的负载下,代码进入竞争状态。地址被传递到pthread_create()的客户端_sock在被复制到连接处理程序()内的sock变量之前,将被下一个accept()调用覆盖。