我正在使用C线程服务器和Java客户端来处理这个示例。这是服务器:
#include <stdio.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <pthread.h>
void* thread_proc(void *arg);
int main(int argc, char *argv[])
{
struct sockaddr_in sAddr;
int listensock;
int result;
int nchildren = 6;
pthread_t thread_id;
int x;
int val;
listensock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
val = 1;
result = setsockopt(listensock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
if (result < 0) {
perror("server");
return 0;
}
sAddr.sin_family = AF_INET;
sAddr.sin_port = htons(6000);
sAddr.sin_addr.s_addr = INADDR_ANY;
result = bind(listensock, (struct sockaddr *) &sAddr, sizeof(sAddr));
if (result < 0) {
perror("exserver5");
return 0;
}
result = listen(listensock, 5);
if (result < 0) {
perror("exserver5");
return 0;
}
for (x = 0; x < nchildren; x++) {
result = pthread_create(&thread_id, NULL, thread_proc, (void *) listensock);
if (result != 0) {
printf("Could not create thread.\n");
return 0;
}
sched_yield();
}
pthread_join (thread_id, NULL);
}
void* thread_proc(void *arg)
{
int listensock, sock;
char buffer[25];
int nread;
listensock = (int) arg;
while (1) {
sock = accept(listensock, NULL, NULL);
printf("client connected to child thread %i with pid %i.\n", pthread_self(), getpid());
while(1){
nread = recv(sock, buffer, 25, 0);
buffer[nread] = '\0';
printf("%s\n", buffer);
send(sock, buffer, nread, 0);
if(nread == '9'){
close(sock);
}
}
printf("client disconnected from child thread %i with pid %i.\n", pthread_self(), getpid());
}
}
这是Java客户端:
import java.net.*;
import java.io.*;
// A client for our multithreaded EchoServer.
public class client
{
public static void main(String[] args)
{
Socket s = null;
// Create the socket connection to the EchoServer.
try
{
s = new Socket("localhost", 6000);
}
catch(UnknownHostException uhe)
{
// Host unreachable
System.out.println("Unknown Host");
s = null;
}
catch(IOException ioe)
{
// Cannot connect to port on given host
System.out.println("Cant connect to server at 6000. Make sure it is running.");
s = null;
}
if(s == null)
System.exit(-1);
BufferedReader in = null;
PrintWriter out = null;
try
{
// Create the streams to send and receive information
in = new BufferedReader(new InputStreamReader(s.getInputStream()));
out = new PrintWriter(new OutputStreamWriter(s.getOutputStream()));
// Since this is the client, we will initiate the talking.
// Send a string.
out.println("Hello");
out.flush();
// receive the reply.
System.out.println("Server Says : " + in.readLine());
// Send a string.
out.println("This");
out.flush();
// receive a reply.
System.out.println("Server Says : " + in.readLine());
// Send a string.
out.println("is");
out.flush();
// receive a reply.
System.out.println("Server Says : " + in.readLine());
// Send a string.
out.println("a");
out.flush();
// receive a reply.
System.out.println("Server Says : " + in.readLine());
// Send a string.
out.println("Test");
out.flush();
// receive a reply.
System.out.println("Server Says : " + in.readLine());
// Send the special string to tell server to quit.
out.println("9");
out.flush();
}
catch(IOException ioe)
{
System.out.println("Exception during communication. Server probably closed connection.");
}
finally
{
try
{
// Close the streams
out.close();
in.close();
// Close the socket before quitting
s.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
}
当我运行客户端时,这是输出:
[root@localhost java]# /opt/jdk1.7.0_03/bin/java client
Server Says : Hello
Server Says : This
Server Says : is
Server Says : a
Server Says : Test
[root@localhost java]#
当我运行服务器时,这是输出:
[root@localhost java]# ./server
client connected to child thread -1215423632 with pid 2854.
Hello
This
is
a
Test
9
9
[root@localhost java]#
当客户端关闭连接时,服务器崩溃。我想在不破坏线程的情况下关闭连接。我该如何解决这个问题?
祝福
P.S这是接受连接的原始线程代码。
void* thread_proc(void *arg)
{
int listensock, sock;
char buffer[25];
int nread;
listensock = (int) arg;
while (1) {
sock = accept(listensock, NULL, NULL);
printf("client connected to child thread %i with pid %i.\n", pthread_self(), getpid());
nread = recv(sock, buffer, 25, 0);
buffer[nread] = '\0';
printf("%s\n", buffer);
send(sock, buffer, nread, 0);
close(sock);
printf("client disconnected from child thread %i with pid %i.\n", pthread_self(), getpid());
}
}
此循环只接受一个字符串并将返回它。然后会退出。我用while循环修改它,但是使用内部while循环(见上文),服务器崩溃了。 我如何修改代码,以便线程可以接受许多字符串并发送许多字符串?
答案 0 :(得分:3)
关闭套接字后需要打破内部循环 - 尝试从已关闭的套接字读取时崩溃:
while(1){
nread = recv(sock, buffer, 25, 0);
buffer[nread] = '\0';
printf("%s\n", buffer);
send(sock, buffer, nread, 0);
if(nread == '9'){
close(sock);
break; // <--- need to break out here
}
}
答案 1 :(得分:1)
while (1) {
sock = accept(listensock, NULL, NULL);
printf("client connected to child thread %i with pid %i.\n", pthread_self(), getpid());
nread = 0;
while(nread >= 0) {
nread = recv(sock, buffer, 25, 0);
if (nread >= 0) {
buffer[nread] = '\0';
printf("%s\n", buffer);
send(sock, buffer, nread, 0);
}
}
close(sock);
printf("client disconnected from child thread %i with pid %i.\n", pthread_self(), getpid());
}