제가 지금 TCP 소켓 통신을 이용한 주소록 백업을 하는데요.
서버는 C로 짰고 클라이언트는 안드로이드 입니다.
현재 제 폰에 있는 주소록이 C서버로 보내는 것까지 확인을 했는데 전체 전화번호부가 다 가지 않네요.
C서버 버퍼 문제인거 같기도 하고 다른 곳에서 답변을 들었더니 String 형식으로 out.println(getList()); 에서 데이터를 전송하고 있는데, 그 전에 String 형식으로 보낼 데이터의 크기를 맨 앞에 달아 보내거나 헤더 메쏘드를 정의하여 헤더를 보내고 데이터를 보내라고 하는데...
클라이언트에서 클래스 통째로 보내면 될것같은데 잘 모르겠네요. 어떤 식으로 수정해야할지 조언좀 부탁드리겠습니다.
------------------------클라이언트---------------------------
TCPsoketTest.java
package com.mnk.TCPsoketTest;
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
import java.util.ArrayList;
import android.app.Activity;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
//import android.widget.EditText;
import android.widget.ListView;
//import android.widget.TextView;
//import android.widget.Toast;
public class TCPsoketTest extends Activity {
ListView listPerson;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// finsal EditText et = (EditText)findViewById(R.id.EditText01);
Button btn = (Button)findViewById(R.id.Button01);
listPerson = (ListView)findViewById(R.id.android_list1);
//getList();
btn.setOnClickListener(new OnClickListener(){
public void onClick(View v){
TCPclient tp = new TCPclient(listPerson.toString());
tp.run();
}
});
}
public ArrayList getList() {
Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
String[] projection = new String[] {
ContactsContract.CommonDataKinds.Phone.NUMBER,
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME };
String[] selectionArgs = null;
// 이름순으로 정렬
String sortOrder = ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME
+ " COLLATE LOCALIZED ASC";
// 조회해서 가져온다(Cursor 사용)
Cursor contactCursor = managedQuery(uri, projection, null,selectionArgs, sortOrder);
// 정보를 담을 array 설정
ArrayList persons = new ArrayList();
if (contactCursor.moveToFirst()) {
do {
persons.add(contactCursor.getString(1) + "/"+ contactCursor.getString(0));
} while (contactCursor.moveToNext());
}
/*
if (contactCursor.moveToFirst()) {
String name;
String phoneNumber;
int nameColumn = contactCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
int phoneColumn = contactCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
String dump = "";
do {
name = contactCursor.getString(nameColumn);
phoneNumber = contactCursor.getString(phoneColumn);
dump +="\nNAME: " + name + "\nNUMBER: " + phoneNumber;
} while ( contactCursor.moveToNext());
*/
// 리스트에 연결할 adapter 설정
ArrayAdapter adp = new ArrayAdapter(this,android.R.layout.simple_list_item_1, persons);
// 리스트뷰에 표시
listPerson.setAdapter(adp);
return persons;
}
private class TCPclient implements Runnable {
private static final String serverIP = "192.168.0.7"; //ex: 192.168.0.100
private static final int serverPort = 8000; // ex: 5555
public TCPclient(String _msg){
}
public void run() {
try {
InetAddress serverAddr = InetAddress.getByName(serverIP);
Log.d("TCP", "C: Connecting...");
Socket socket = new Socket(serverAddr, serverPort);
try {
//Log.d("TCP", "C: Sending: '" + msg + "'");
PrintWriter out = new PrintWriter( new BufferedWriter( new OutputStreamWriter(socket.getOutputStream(),"EUC-KR")),true);
out.println(getList());
out.flush();
Log.d("TCP", "C: Sent.");
Log.d("TCP", "C: Done.");
//BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream(),"EUC-KR"));
//return_msg = in.readLine();
out.flush();
Log.d("TCP", "C: Server send to me this message -->" + getList());
} catch(Exception e) {
Log.e("TCP", "C: Error1", e);
} finally {
socket.close();
}
} catch (Exception e) {
Log.e("TCP", "C: Error2", e);
}
}
}
}
---------------------서버-------------------------
main.cpp
#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
#define BUF_LEN 18384
// WinSock DLL을 사용할 버전
#define VERSION_MAJOR 2
#define VERSION_MINOR 0
int main(int argc, char* argv[])
{
WORD VersionRequested = MAKEWORD(VERSION_MAJOR, VERSION_MINOR);
WSADATA WsaData; // receives data from WSAStartup
struct sockaddr_in server_addr, client_addr; // socket address
SOCKET server_fd, client_fd; // socket handle
char buf[BUF_LEN+1];
int len, msg_size;
// Load WinSock DLL
if ( WSAStartup(VersionRequested, &WsaData) != 0 ) {
return -1;
}
// socket 생성
server_fd = socket( PF_INET, SOCK_STREAM, 0 );
memset( &server_addr, 0, sizeof(struct sockaddr) );
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons(atoi(argv[1]));
// bind() 호출
if( bind(server_fd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) < 0 ){
printf("Server: Can't bind local address.\n");
exit(0);
}
// 소켓을 수동 대기모드로 세팅
listen(server_fd, 5);
// iterative echo 서비스 수행
while(1) {
printf("Server : waiting connection request.\n");
len = sizeof(client_addr);
// 연결요청을 기다림
client_fd = accept(server_fd, (struct sockaddr *)&client_addr, &len);
if(client_fd < 0) {
printf("Server: accept failed.\n");
exit(0);
}
printf("Server : A client connected.\n");
while(1){
msg_size = recv(client_fd, buf, sizeof(buf), 0);
buf[msg_size]='\0';
printf("Message : %s",buf);
if(strcmp(buf,"##"))
break;
}
send(client_fd, buf, msg_size, 0);
closesocket(client_fd);
}
closesocket(server_fd);
WSACleanup(); // Unload WinSock DLL
return 0;
}
전화번호부를 C 서버에 저장하고싶은데 어떤식으로 보내고 어떤식으로 받아야 효율적이고 정확하게 송수신이 되는지 답변 좀 부탁드리겠습니다ㅠ




ArrayList를 PrintWriter를 통해서 보내기 보단,
서버처럼 클라이언트도 바이트 단위로 보내는게 맞지 않나 싶네요~(물론 이 과정을 쉽게 해주는게 PrintWriter인듯 한데 말이죠~)
자바로 만든 서버라면 클라이언트가 저렇게 데이터를 보내도 무난할듯 한데~
C 서버라면 바이트 단위로 보내는게 맞는것 같습니다.
물론 서버와 클라이언트간의 정해진 프로토콜이 있으면 더 좋겠죠~