Java(서버) 와 C(클라이언트) 간에 통신하는 소켓프로그래밍문제인데요..

mmx822의 이미지

안녕하세요..
과제를 하는데.. 잘안되서 이렇게 포럼을 작성합니다..
일단 과제의 목표는.. java로 작성된 서버와 c로 작성된 클라이언트 간에 소켓프로그래밍을 통해서 통신하는 것인데요..
실은 아주 간단한 것입니다..
클라이언트에서 소문자를 입력해서 서버로 보내면... 자바로 작성된 서버에서는 그걸 대문자로 바꾸고 클라이언트로 넘겨주게되고..
클라이언트는 그걸 프린트하는 형식인데요..
이상하게 아래의 코드로는 메세지가 제대로 전달되질 않습니다..;
제가 자바는 아주 많이 초보라서.. 어디를 바꿔야하는지도 모르겠어서 이렇게 포럼을 작성합니다..
아래는 코드입니다..

이건 자바로 작성된 서버
 
import java.io.*;
import java.net.*;
 
class TCP_Server_Java {
	public static void main(String argv[]) throws Exception
	{
		String clientSentence;
		String capitalizedSentence;
		ServerSocket welcomeSocket = new ServerSocket(1234);
		while(true)
		{
			Socket connectionSocket = welcomeSocket.accept();
			BufferedReader inFromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
			DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream());
			clientSentence = inFromClient.readLine();
			capitalizedSentence = clientSentence.toUpperCase() + '\n';
			outToClient.writeBytes(capitalizedSentence);
		}
	}
}
 
이건 C로 작성된 클라이언트
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>
 
#define BUF_SIZE 1024
 
int main(int argc, char *argv[])
{
	WSADATA wsaData;
	SOCKET hSocket;
	char message[BUF_SIZE];
	char modifiedmessage[BUF_SIZE];
	int strLen;
	SOCKADDR_IN servAdr;
 
	if(argc!=3) {
		printf("Usage : %s <IP> <port>\n", argv[0]);
		exit(1);
	}
 
	WSAStartup(MAKEWORD(2, 2), &wsaData);
 
	hSocket=socket(PF_INET, SOCK_STREAM, 0);  
 
	memset(&servAdr, 0, sizeof(servAdr));
	servAdr.sin_family=AF_INET;
	servAdr.sin_addr.s_addr=inet_addr(argv[1]);
	servAdr.sin_port=htons(atoi(argv[2]));
 
	connect(hSocket, (SOCKADDR*)&servAdr, sizeof(servAdr));
		scanf("%s",message);
		send(hSocket, message, strlen(message), 0);
		strLen=recv(hSocket, modifiedmessage, strlen(modifiedmessage), 0);
		modifiedmessage[strLen]='\0';
		printf("Message from server: %s", modifiedmessage);
	closesocket(hSocket);
	WSACleanup();
	return 0;
}

어디가 잘못된 것인지.. 정확히 그걸 왜 그렇게 바꿔야 정상 작동하는지 알려주세요~

gilgil의 이미지

Java는 잘 모르겠지만 Java 수신 코드를 보면

clientSentence = inFromClient.readLine();

아마 method 이름을 보니 CR(혹은 LF)가 들어 올 때까지 기다리고 있는 듯 하군요.

그런데 송신 코드를 보면

scanf("%s",message);
send(hSocket, message, strlen(message), 0);

여기에서는 CRLF가 송신이 되지 않습니다. 송신측에서 CRLF를 붙여서 보내어 보세요.

scanf("%s",message);
strcat(message, "\r\n");
send(hSocket, message, strlen(message), 0);
mmx822의 이미지

케리지리턴과 뉴라인을 붙여도 여전히 서버에서 한글자만 답해줍니다..
즉.. 클라이언트에서 abcd 를 보내면 서버에서는 클라이언트에게 A 만을 보내고 끝을내는군요..ㅜㅜ
아..정말 지금 답답해 죽겠네요.. 이게 왜 이렇게 안 되는건지.. 제가 자바만 똑바로 알아도 이런사태는 없을거같은데..
당췌 자바의 BufferedReader 가 정확히 어떤식으로 쓰이는건지도 모르겠으니..쩝..
다른 방법은 없을런지요??

gilgil의 이미지

1 Byte ASCII code와 n Byte UNI code와 같이 코드 체계가 달라서 그런 거 아닐까요?
Wireshark 등으로 패킷을 잡아서 디버깅해 보시기 바랍니다.

mmx822의 이미지

C(서버) 와 Java(클라이언트)도 있는데 이건 잘 돌아갑니다..
그 얘기는 코드 체계의 문제는 아닌거같은데.. 혹시 저 위의 코딩에서 스트링의 첫번째 글자빼고 쏵 날아가버릴만한 곳을 찾을 수 있으실까요? ㅜㅜ
혹시 모르니..C(서버) Java(클라이언트) 코딩도 올려보겠습니다..

C서버코딩
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <winsock2.h>
 
#define BUF_SIZE 1024
 
int main(int argc, char *argv[])
{
	WSADATA wsaData;
	SOCKET hServSock, hClntSock;
	char message[BUF_SIZE];
	char modifiedmessage[BUF_SIZE];
	int strLen, i;
 
	SOCKADDR_IN servAdr, clntAdr;
	int clntAdrSize;
 
	if(argc!=2) {
		printf("Usage : %s <port>\n", argv[0]);
		exit(1);
	}
 
	WSAStartup(MAKEWORD(2, 2), &wsaData);
 
	hServSock=socket(PF_INET, SOCK_STREAM, 0);   
 
	memset(&servAdr, 0, sizeof(servAdr));
	servAdr.sin_family=AF_INET;
	servAdr.sin_addr.s_addr=htonl(INADDR_ANY);
	servAdr.sin_port=htons(atoi(argv[1]));
 
	bind(hServSock, (SOCKADDR*)&servAdr, sizeof(servAdr));
 
	listen(hServSock, 5);
 
	clntAdrSize=sizeof(clntAdr);
 
	while(1)
	{
		hClntSock=accept(hServSock, (SOCKADDR*)&clntAdr, &clntAdrSize);
		while((strLen=recv(hClntSock, message, BUF_SIZE, 0))!=0)
		{
			for(i=0; message[i]!='\0'; i++)
				modifiedmessage[i] = toupper(message[i]);
			modifiedmessage[i] = '\0';
			send(hClntSock, modifiedmessage, strLen, 0);
		}
		closesocket(hClntSock);
	}
	closesocket(hServSock);
	WSACleanup();
	return 0;
}
 
java 클라이언트 코딩
 
import java.io.*;
import java.net.*;
 
class TCP_Client_Java {
	public static void main(String argv[]) throws Exception
	{
		String sentence;
		String modifiedSentence;
		System.out.print("Input Character : ");
		BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
		Socket clientSocket = new Socket("127.0.0.1",1234);
		DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
		BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
		sentence = inFromUser.readLine();
		outToServer.writeBytes(sentence +'\n');
		modifiedSentence = inFromServer.readLine();
		System.out.println("From Server : " + modifiedSentence);
		clientSocket.close();
	}
}
emptynote의 이미지

제가 생각하기엔
"strLen=recv(hSocket, modifiedmessage, strlen(modifiedmessage), 0);"
==> 여기서 strlen(modifiedmessage) 이 잘못된듯합니다. 문자열 받기전에 문자열 크기를 구하네요.

출처 : http://forum.falinux.com/zbxe/?document_srl=441107
--------- 인용 -----------
recv() 함수는 소켓으로부터 데이터를 수신합니다.
헤더 #include
#include
형태 int recv(int s, void *buf, size_t len, int flags);
인수
int s : 소켓 디스크립터
void *buf : 수신할 버퍼 포인터 데이터
size_t len : 버퍼의 바이트 단위 크기
int flags : 아래와 같은 옵션을 사용할 수 있습니다.
flags 옵션 설명
MSG_DONTWAIT 수신을 위해 대기가 필요하다면 기다리지 않고 -1을 반환하면서 바로 복귀
MSG_NOSIGNAL 상대방과 연결이 끊겼을 때, SIGPIPE 시그널을 받지 않도록 합니다.
반환
-1 이외 : 실제 수신한 바이트 수
-1 : 실패

mmx822의 이미지

그래서 그걸 BUF_SIZE-1 로했지만.. 여전히 한글자만 대문자로 바뀌고 한글자만 출력된 뒤 종료되네요..
아..오늘 자정까지 내야되는데 어떡하죠 ㅜㅜ

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.